package xcmg.device.service.warehouse;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.DataDictionaryDO;
import xcmg.device.dao.entity.MaterialLocationRelationDO;
import xcmg.device.dao.entity.PriMaterialsDO;
import xcmg.device.dao.entity.PubMaterialsDO;
import xcmg.device.dao.entity.barcode.BarcodeManageDO;
import xcmg.device.dao.entity.company.CompanyDealerDO;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptLinkDO;
import xcmg.device.dao.entity.delivery.DeliveryReceiptMaterialDO;
import xcmg.device.dao.entity.delivery.ReceiptInDO;
import xcmg.device.dao.entity.warehouse.WarehouseDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryDetailDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryRecordDO;
import xcmg.device.dao.entity.warehouse.WarehouseInOutBaseDO;
import xcmg.device.dao.entity.warehouse.WarehouseInboundDO;
import xcmg.device.dao.entity.warehouse.WarehouseInboundRecordDO;
import xcmg.device.dao.entity.warehouse.WarehouseInventoryDO;
import xcmg.device.dao.mapper.BarcodeManageMapper;
import xcmg.device.dao.mapper.BoxupDetailMapper;
import xcmg.device.dao.mapper.CompanyDealerMapper;
import xcmg.device.dao.mapper.DataDictionaryMapper;
import xcmg.device.dao.mapper.DeliveryReceiptDetailMapper;
import xcmg.device.dao.mapper.MaterialLocationRelationMapper;
import xcmg.device.dao.mapper.MaterialWarehouseUserMapper;
import xcmg.device.dao.mapper.PriMaterialsMapper;
import xcmg.device.dao.mapper.PubMaterialsMapper;
import xcmg.device.dao.mapper.SaleIntentionDetailMapper;
import xcmg.device.dao.mapper.abnormal.AbnormalOutDetailMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteDetailMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptLinkMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptMapper;
import xcmg.device.dao.mapper.delivery.DeliveryReceiptMaterialMapper;
import xcmg.device.dao.mapper.delivery.ReceiptInMapper;
import xcmg.device.dao.mapper.threeGuaranteesPur.ThreeGuaranteesOutDetailMapper;
import xcmg.device.dao.mapper.warehouse.AbnormalInDetailMapper;
import xcmg.device.dao.mapper.warehouse.MaterialTransferMapper;
import xcmg.device.dao.mapper.warehouse.RegionAllotDetailMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseAreaLocationDOMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDOMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryDetailMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryRecordMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInboundMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInboundRecordMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInventoryMapper;
import xcmg.device.infra.CompanyConstants;
import xcmg.device.infra.DateUtil;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.enums.BarcodeStatus;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.infra.enums.ForwardBarcodeLableEnum;
import xcmg.device.service.abnormal.AbnormalOutService;
import xcmg.device.service.basic.MaterialsService;
import xcmg.device.service.company.CompanyInfoService;
import xcmg.device.service.materialsSchedule.MaterialsScheduleService;
import xcmg.device.service.threeGuaranteesPur.ThreeGuaranteesOutService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.abnormal.AbnormalAddVO;
import xcmg.device.service.vo.abnormal.AbnormalOutDetailVO;
import xcmg.device.service.vo.basic.MaterialLocationRelationVO;
import xcmg.device.service.vo.basic.MaterialsVO;
import xcmg.device.service.vo.basic.WarehouseInfoConditionVO;
import xcmg.device.service.vo.basic.WarehouseStockInfoVO;
import xcmg.device.service.vo.boxup.BoxupMaterialsQuery;
import xcmg.device.service.vo.company.CompanyInfoVO;
import xcmg.device.service.vo.delivery.BoxUpDeliveryNoteVO;
import xcmg.device.service.vo.initialInventory.MaterialsEnableStock;
import xcmg.device.service.vo.materialsSchedule.MaterialsScheduleAddVO;
import xcmg.device.service.vo.materialsSchedule.MaterialsScheduleDetailVO;
import xcmg.device.service.vo.threeGuaranteesPur.ThreeGuaranteesOutAddVO;
import xcmg.device.service.vo.threeGuaranteesPur.ThreeGuaranteesOutDetailVO;
import xcmg.device.service.vo.warehouse.AbnormalInAddVO;
import xcmg.device.service.vo.warehouse.AbnormalInDetailVO;
import xcmg.device.service.vo.warehouse.FindMaterialsInfos;
import xcmg.device.service.vo.warehouse.FindMaterialsNumParam;
import xcmg.device.service.vo.warehouse.FindMaterialsNumVO;
import xcmg.device.service.vo.warehouse.MaterialNoAndAmountsVO;
import xcmg.device.service.vo.warehouse.MaterialTransferAddVO;
import xcmg.device.service.vo.warehouse.MaterialTransferDetailVO;
import xcmg.device.service.vo.warehouse.MaterialTransferVO;
import xcmg.device.service.vo.warehouse.StockAmountInfo;
import xcmg.device.service.vo.warehouse.WarehoseIntentionDetialVO;
import xcmg.device.service.vo.warehouse.WarehouseInOutBaseVO;
import xcmg.device.service.vo.warehouse.WarehouseInventoryCyVO;
import xcmg.device.service.vo.warehouse.WarehouseInventoryStockVO;
import xcmg.device.service.vo.warehouse.WarehouseInventoryTransferWithOutBarCodeVO;
import xcmg.device.service.vo.warehouse.WarehouseInventoryVO;
import xcmg.device.service.vo.warehouse.app.EnableAndOccupyVO;
import xcmg.device.service.vo.warehouse.app.WarehouseInventoryBatchFrozenVO;
import xcmg.device.service.vo.warehouse.app.WarehouseInventoryBatchTransferVO;
import xcmg.device.service.vo.warehouse.app.WarehouseInventoryFrozenVO;
import xcmg.device.service.vo.warehouse.app.WarehouseInventoryTransferVO;
import xcmg.device.service.vo.warehouse.sap.ObligateHeaderVO;
import xcmg.device.service.vo.warehouse.sap.ObligateVO;
import xcmg.device.service.warehouse.allot.RegionAllotService;
import xcmg.device.util.CompanyUtil;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.PageHelperPlus;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class WarehouseInventoryService {

    private static final Log log = LogFactory.getLog(WarehouseInventoryService.class);

    @Autowired
    private WarehouseInventoryMapper warehouseInventoryMapper;

    @Autowired
    private FastGenClient fastGenClient;

    @Autowired
    private WarehouseAreaLocationDOMapper warehouseAreaLocationDOMapper;

    @Autowired
    private WarehouseInboundRecordMapper warehouseInboundRecordMapper;


    @Autowired
    private BarcodeManageMapper barcodeManageMapper;

    @Autowired
    private WarehouseInboundMapper warehouseInboundMapper;

    @Autowired
    private WarehouseDeliveryDetailMapper warehouseDeliveryDetailMapper;

    @Autowired
    private SaleIntentionDetailMapper saleIntentionDetailMapper;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private DataDictionaryMapper dataDictionaryMapper;

    @Autowired
    private CommonService commonService;

    @Autowired
    private AbnormalInService abnormalInService;

    @Autowired
    private AbnormalOutService abnormalOutService;

    @Autowired
    private ThreeGuaranteesOutService threeGuaranteesOutService;

    @Autowired
    private RegionAllotService regionAllotService;

    @Autowired
    private MaterialsScheduleService materialsScheduleService;


    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private WarehouseDeliveryMapper warehouseDeliveryMapper;

    @Autowired
    private MaterialLocationRelationMapper materialLocationRelationMapper;

    @Autowired
    private MaterialTransferService materialTransferService;

    @Autowired
    private PriMaterialsMapper priMaterialsMapper;

    @Autowired
    private CompanyDealerMapper companyDealerMapper;

    @Autowired
    private WarehouseDOMapper warehouseDOMapper;

    @Autowired
    private MaterialTransferMapper materialTransferMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private WarehouseDeliveryRecordMapper warehouseDeliveryRecordMapper;

    @Autowired
    private DeliveryReceiptMapper deliveryReceiptMapper;

    @Autowired
    private DeliveryReceiptLinkMapper deliveryReceiptLinkMapper;

    @Autowired
    private DeliveryNoteDetailMapper deliveryNoteDetailMapper;
//
//    @Autowired
//    private DeliveryReceiptDetailMapper deliveryReceiptDetailMapper;

    @Autowired
    private ThreeGuaranteesOutDetailMapper threeGuaranteesOutDetailMapper;

    @Autowired
    private RegionAllotDetailMapper regionAllotDetailMapper;

    @Autowired
    private AbnormalOutDetailMapper abnormalOutDetailMapper;

    @Autowired
    private BoxupDetailMapper boxupDetailMapper;

    @Autowired
    private MaterialWarehouseUserMapper materialWarehouseUserMapper;

    @Autowired
    private MaterialsService materialsService;

    @Value("${sap.area.code:0}")
    private String sapCode;

    private static final String WJ_ORG_ID = "214678683422556160";

    private static final String WJ_SAP_CODE = "9005";

    private static final String INVENTORY_EXPORT = "inventory_export";
    @Autowired
    private DepartmentWarehouseRelationService relationService;

    @Autowired
    private ReceiptInMapper receiptInMapper;

    @Autowired
    private DeliveryReceiptMaterialMapper deliveryReceiptMaterialMapper;

//    @Autowired
//    private AbnormalInDetailMapper abnormalInDetailMapper;

    @Autowired
    private PubMaterialsMapper pubMaterialsMapper;
    
    @Autowired
    private CompanyUtil companyUtil;

    /**
     * @Author: WangKe
     * @Description: 根据条码查询零件
     * @Date: 15:08 2018/1/17 0017
     */
    public WarehouseInventoryDO findByBarCode(String barCode, String orgId) {
        return warehouseInventoryMapper.selectByBarCode(barCode, orgId);
    }

    public WarehouseInventoryVO findByBarCodeForSplit(String barCode, String orgId) throws Exception {
        BarcodeManageDO barcodeDO = barcodeManageMapper.item(barCode, orgId);
        if (barcodeDO == null) {
            throw new Exception("条码不存在");
        }
        List<BarcodeManageDO> barcodeManageDOList = new ArrayList<>();
        if (barcodeDO.getBarcodeFlag() == 0) { //总条码时查询分条码列表
            barcodeManageDOList.addAll(barcodeManageMapper.findByTotalBarcode(barCode, orgId));
        } else {
            barcodeManageDOList.add(barcodeDO);
        }
        if (ListUtil.isNullOrEmpty(barcodeManageDOList)) {
            throw new Exception("条码不存在");
        }
        if (barcodeManageDOList.size() > 1) {
            throw new Exception("请扫描分条码");
        }
        BarcodeManageDO barcodeManageDO = barcodeManageDOList.get(0);
        if ("3".equals(barcodeManageDO.getBarcodeStatus())) {
            throw new Exception("条码已拆分");
        }
        WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
        inventoryVO.setMaterialNo(barcodeManageDO.getMaterialsNo());
        inventoryVO.setMaterialName(barcodeManageDO.getMaterialsDes());
        inventoryVO.setAmount(barcodeManageDO.getCurrentQty());
        inventoryVO.setBarCode(barcodeManageDO.getBarcode());
        inventoryVO.setBarcodeStatus(barcodeManageDO.getBarcodeStatus());
        inventoryVO.setTotalQty(barcodeManageDO.getTotalQty());
        inventoryVO.setStatusDesc(barcodeManageDO.getStatusDesc());
        if ("1".equals(barcodeManageDO.getBarcodeStatus())) {
            WarehouseInventoryDO inventoryDO = warehouseInventoryMapper.selectByBarCode(barcodeManageDO.getBarcode(), orgId);
            if (inventoryDO != null) {
                inventoryVO.setLocationCode(inventoryDO.getLocationCode());
            }
        }
        return inventoryVO;
    }

    public List<WarehouseInventoryVO> findByAllBarCode(String barCode, String orgId) {
        List<WarehouseInventoryVO> inventoryVOList = new ArrayList<>();
        BarcodeManageDO barcodeDO = barcodeManageMapper.item(barCode, orgId);
        if (barcodeDO == null) {
            return inventoryVOList;
        }
        List<BarcodeManageDO> barcodeManageDOList = new ArrayList<>();
        if (barcodeDO.getBarcodeFlag() == 0) { //总条码时查询分条码列表
            barcodeManageDOList.addAll(barcodeManageMapper.findByTotalBarcode(barCode, orgId));
        } else {
            barcodeManageDOList.add(barcodeDO);
        }
        if (ListUtil.isNullOrEmpty(barcodeManageDOList)) {
            return inventoryVOList;
        }
        List<WarehouseInventoryVO> dataList = new ArrayList<>();
        for (BarcodeManageDO barcodeManageDO : barcodeManageDOList) {
            WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
            inventoryVO.setMaterialNo(barcodeManageDO.getMaterialsNo());
            inventoryVO.setMaterialName(barcodeManageDO.getMaterialsDes());
            inventoryVO.setAmount(barcodeManageDO.getCurrentQty());
            inventoryVO.setBarCode(barcodeManageDO.getBarcode());
            inventoryVO.setBarcodeStatus(barcodeManageDO.getBarcodeStatus());
            inventoryVO.setTotalQty(barcodeManageDO.getTotalQty());
            inventoryVO.setStatusDesc(barcodeManageDO.getStatusDesc());

            dataList.add(inventoryVO);
        }
        return dataList;
    }

    public List<WarehouseInventoryCyVO> queryByCyBarcode(BarcodeManageDO barcodeDO, String orgId) {
        List<WarehouseInventoryCyVO> inventoryVOList = new ArrayList<>();
        if (barcodeDO == null) {
            return inventoryVOList;
        }
        List<BarcodeManageDO> barcodeManageDOList = new ArrayList<>();
        if (barcodeDO.getBarcodeFlag() == 0) { //总条码时查询分条码列表
            barcodeManageDOList.addAll(barcodeManageMapper.findByTotalBarcode(barcodeDO.getBarcode(), orgId));
        } else {
            barcodeManageDOList.add(barcodeDO);
        }
        if (ListUtil.isNullOrEmpty(barcodeManageDOList)) {
            return inventoryVOList;
        }
        WarehouseInventoryCyVO inventoryVO;
        for (BarcodeManageDO barcodeManageDO : barcodeManageDOList) {
            inventoryVO = new WarehouseInventoryCyVO();
            inventoryVO.setBarcode(barcodeManageDO.getBarcode());
            inventoryVO.setMaterialNo(barcodeManageDO.getMaterialsNo());
            inventoryVO.setMaterialName(barcodeManageDO.getMaterialsDes());
            inventoryVO.setBatchId(barcodeManageDO.getBatchId());
            inventoryVO.setSplirid(barcodeManageDO.getSplirid());
            inventoryVOList.add(inventoryVO);
        }
        return inventoryVOList;
    }

    /**
     * @Author: WangKe
     * @Description: 装箱扫码时验证
     * @Date: 2018/12/17 0017
     */
    public List<WarehouseInventoryVO> findByBarcodeForBoxUp(String barcode, String receiptNo, String orgId) throws Exception {
        List<WarehouseInventoryVO> inventoryVOList = new ArrayList<>();
        BarcodeManageDO barcodeDO = barcodeManageMapper.item(barcode, orgId);
        if (barcodeDO == null) {
            return inventoryVOList;
        }
        List<BarcodeManageDO> barcodeManageDOList = new ArrayList<>();
        if (barcodeDO.getBarcodeFlag() == 0) { //总条码时查询分条码列表
            barcodeManageDOList.addAll(barcodeManageMapper.findByTotalBarcode(barcode, orgId));
        } else {
            barcodeManageDOList.add(barcodeDO);
        }
        if (ListUtil.isNullOrEmpty(barcodeManageDOList)) {
            return inventoryVOList;
        }
        DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.itemByNo(receiptNo);
        if (deliveryReceiptDO == null) {
            throw new Exception(ErrorCode.DeliveryReceiptInfoNotExists.getDesc());
        }
        if (deliveryReceiptDO.getCommitType().equals(1)) {
            throw new Exception(ErrorCode.DeliveryReceiptCommited.getDesc());
        }
        List<DeliveryReceiptLinkDO> deliveryReceiptLinkDOList = deliveryReceiptLinkMapper.list(deliveryReceiptDO.getId());
        if (deliveryReceiptLinkDOList == null || deliveryReceiptLinkDOList.size() <= 0) {
            throw new Exception(ErrorCode.DeliveryReceiptNDeliveryNote.getDesc());
        }
        List<WarehouseInventoryVO> dataList = new ArrayList<>();
        for (BarcodeManageDO barcodeManageDO : barcodeManageDOList) {
            WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
            inventoryVO.setMaterialNo(barcodeManageDO.getMaterialsNo());
            inventoryVO.setMaterialName(barcodeManageDO.getMaterialsDes());
            inventoryVO.setAmount(barcodeManageDO.getCurrentQty());
            inventoryVO.setBarCode(barcodeManageDO.getBarcode());
            inventoryVO.setBarcodeStatus(barcodeManageDO.getBarcodeStatus());
            inventoryVO.setTotalQty(barcodeManageDO.getTotalQty());
            inventoryVO.setStatusDesc(barcodeManageDO.getStatusDesc());

            dataList.add(inventoryVO);
        }
        for (BarcodeManageDO barcodeManageDO : barcodeManageDOList) {
            BoxupMaterialsQuery boxupMaterialsQuery = new BoxupMaterialsQuery();
            boxupMaterialsQuery.setMaterialsNo(barcodeManageDO.getMaterialsNo());
            boxupMaterialsQuery.setDeliveryReceiptLinkDOList(deliveryReceiptLinkDOList);

            boxupMaterialsQuery.setBarcode(barcodeManageDO.getBarcode());
            boxupMaterialsQuery.setOrgId(orgId);
            List<WarehouseDeliveryRecordDO> deliveryNoteNos = warehouseDeliveryRecordMapper.findBusinessOrder(boxupMaterialsQuery);
            if (ListUtil.isNullOrEmpty(deliveryNoteNos)) {
                throw new Exception(barcodeManageDO.getBarcode() + ",单据无此零件或该零件未出库");
            }
            for (WarehouseDeliveryRecordDO deliveryNoteNo : deliveryNoteNos) {
                if (!StringUtil.isNullOrEmpty(deliveryNoteNo.getDeliveryReceiptNo())) {
                    barcodeManageDO.setCurrentQty(deliveryNoteNo.getAmount());
                }
                BoxUpDeliveryNoteVO boxUpDeliveryNoteVO = new BoxUpDeliveryNoteVO();
                switch (deliveryReceiptDO.getBillType()) {
                    case "XGFT":
                        boxUpDeliveryNoteVO = deliveryNoteDetailMapper.itemByNoAndMaterialsNo(orgId, deliveryNoteNo.getBusinessOrder(), barcodeManageDO.getMaterialsNo());
                        break;
                    case "XGSC":
                        boxUpDeliveryNoteVO = threeGuaranteesOutDetailMapper.itemByNoAndMaterialsNo(orgId, deliveryNoteNo.getBusinessOrder(), barcodeManageDO.getMaterialsNo());
                        break;
                    case "XGQD":
                        boxUpDeliveryNoteVO = regionAllotDetailMapper.itemByNoAndMaterialsNo(orgId, deliveryNoteNo.getBusinessOrder(), barcodeManageDO.getMaterialsNo());
                        break;
                    case "XGFC":
                        boxUpDeliveryNoteVO = abnormalOutDetailMapper.itemByNoAndMaterialsNo(orgId, deliveryNoteNo.getBusinessOrder(), barcodeManageDO.getMaterialsNo());
                        break;
                }
                if (boxUpDeliveryNoteVO == null) {
                    throw new Exception("业务单据无此零件");
                }
                BigDecimal paceNumberSum = boxUpDeliveryNoteVO.getPackNumber().add(barcodeManageDO.getCurrentQty());
                if (boxUpDeliveryNoteVO.getInventoryOutAmount().compareTo(paceNumberSum) < 0) {
                    throw new Exception(barcodeManageDO.getBarcode() + "本次发货数量大于剩余数量");
                }
                Integer barcodeCount = boxupDetailMapper.barcodeCount(barcodeManageDO.getBarcode(), boxUpDeliveryNoteVO.getDeliveryNoteId());
                if (barcodeCount > 0) {
                    throw new Exception(barcodeManageDO.getBarcode() + "重复装箱");
                }
            }
        }
        return dataList;
    }

    /**
     * 从BASIC_PRI_MATERIALS中获取是否关键件的属性
     * @param inventoryVOList
     */
    public void getCrucialDevice(List<WarehouseInventoryVO> inventoryVOList) {
        if (inventoryVOList != null) {
            for (WarehouseInventoryVO warehouseInventoryVO : inventoryVOList) {
                List<PriMaterialsDO> priMaterialsDOS = priMaterialsMapper.listByNoAndOrgId(warehouseInventoryVO.getMaterialNo(),warehouseInventoryVO.getOrgId());
                if (priMaterialsDOS != null && priMaterialsDOS.size() > 0 ) {
                    warehouseInventoryVO.setCrucialDevice(priMaterialsDOS.get(0).getCrucialDevice());
                }
            }
        }
    }

    /**
     * @Author: WangKe
     * @Description: 根据条码从库存表中获取零件信息
     * @Date: 2018/3/16 0016
     */
    public ErrorCode findByBarCodeFromInventory(String businessOrder, String barCode, String orgId, List<WarehouseInventoryVO> inventoryVOList, Integer frozen) throws Exception {
        BarcodeManageDO barcodeDO = barcodeManageMapper.item(barCode, orgId);
        if (barcodeDO == null) {
            return ErrorCode.WarehouseBarcodeNotFound;
        }

        if("2".equals(barcodeDO.getBarcodeStatus())){
            return ErrorCode.WarehouseOutboundDuplicate;
//            throw new Exception(ErrorCode.WarehouseOutboundDuplicate.getDesc());
        }

        WarehouseDeliveryDO deliveryDO = null;
        if (!StringUtil.isNullOrEmpty(businessOrder)) {
            deliveryDO = warehouseDeliveryMapper.findByBusinessOrder(businessOrder, orgId);
        }

        List<String> barcdoeList = new ArrayList<>();
        if (barcodeDO.getBarcodeFlag() == 0) { //总条码时查询分条码列表
            barcdoeList.addAll(barcodeManageMapper.findBarcodeByTotalBarcode(barCode, orgId));
        } else {
            barcdoeList.add(barCode);
        }
        if (ListUtil.isNullOrEmpty(barcdoeList)) {
            return ErrorCode.WarehouseBarcodeNotFound;
        }
        List<WarehouseInventoryDO> inventoryDOList = warehouseInventoryMapper.selectByBarCodeList(barcdoeList, orgId, frozen);

        if (!ListUtil.isNullOrEmpty(inventoryDOList)) {
            //拆分数量
            BigDecimal detachNum = BigDecimal.ZERO;
            if (deliveryDO != null) {
                List<WarehouseDeliveryDetailDO> warehouseDeliveryDetailDOs = warehouseDeliveryDetailMapper.itemInfosByMaterialsNo(orgId, deliveryDO.getBusinessOrder(), inventoryDOList.get(0).getMaterialNo());
                if (CollectionUtils.isEmpty(warehouseDeliveryDetailDOs)) {
                    throw new Exception("条码零件与单据零件不匹配");
                }
                //出库事务表需要出库的数量减去实际出库数量=剩余待出库数量
                for(WarehouseDeliveryDetailDO warehouseDeliveryDetailDO: warehouseDeliveryDetailDOs) {
                    detachNum = detachNum.add(warehouseDeliveryDetailDO.getAmount().subtract(warehouseDeliveryDetailDO.getRealAmount() == null ? BigDecimal.ZERO : warehouseDeliveryDetailDO.getRealAmount()));
                }
                if(detachNum.compareTo(BigDecimal.ZERO) == 0) {
                    throw new Exception("零件已出库");
                }

                inventoryDOList = filterInventoryList(deliveryDO, inventoryDOList, orgId);

                BigDecimal tempAmount1 = BigDecimal.ZERO;
                BigDecimal tempAmount2 = BigDecimal.ZERO;
                for (WarehouseInventoryDO inventoryDO : inventoryDOList) {
                    WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
                    BeanUtils.copyProperties(inventoryDO, inventoryVO);
                    tempAmount1 = tempAmount1.add(inventoryDO.getAmount());
                    if (detachNum.compareTo(tempAmount1) < 0) {
                        inventoryVO.setDetachNum(detachNum.subtract(tempAmount2));//设置拆分数量
                    } else {
                        inventoryVO.setDetachNum(BigDecimal.ZERO);//设置拆分数量
                    }
                    inventoryVOList.add(inventoryVO);
                    tempAmount2 = tempAmount2.add(inventoryDO.getAmount());

                    if (inventoryVO.getDetachNum().compareTo(BigDecimal.ZERO) > 0 || detachNum.compareTo(tempAmount2) == 0) {
                        break;
                    }
                }
            } else {
                for (WarehouseInventoryDO inventoryDO : inventoryDOList) {
                    WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
                    BeanUtils.copyProperties(inventoryDO, inventoryVO);
                    inventoryVO.setDetachNum(BigDecimal.ONE);
                    inventoryVOList.add(inventoryVO);
                }
            }
        }
        LogHelper.monitor("PDA出库条码拆分出参"+ JSON.toJSONString(inventoryVOList));
        return ErrorCode.Success;
    }

    private List<WarehouseInventoryDO> filterInventoryList(WarehouseDeliveryDO deliveryDO, List<WarehouseInventoryDO> inventoryDOList, String orgId) throws Exception {
        //云内送货单出库不校验仓库信息
        if (StringUtils.equals(BillDesc.AgentAllot.getDesc(), deliveryDO.getBusinessSingle())
                || StringUtils.equals(BillDesc.SendBill.getDesc(), deliveryDO.getBusinessSingle())){
            return inventoryDOList;
        }
        List<WarehouseInventoryDO> dataList = new ArrayList<>();
        WarehouseDO warehouseDO = warehouseDOMapper.itemByWarehouseCode(orgId, deliveryDO.getWarehouseCode());
        if (warehouseDO == null) {
            throw new Exception("未找到仓库信息");
        }
        //过滤获取库存表中仓库与本次出库仓库能对上的库存记录
        for (WarehouseInventoryDO inventoryDO : inventoryDOList) {
            if (deliveryDO.getWarehouseCode().equals(inventoryDO.getWarehouseCode())) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(inventoryDO.getCreateDate());
                calendar.add(Calendar.DATE, -1);
                Date now = calendar.getTime();
                if (warehouseDO.getFirstInOut().equals(new Integer("1")) && warehouseInventoryMapper.earliestInventory(orgId, inventoryDO.getMaterialNo(),
                        inventoryDO.getWarehouseCode(), inventoryDO.getAreaCode(), now) > 0) {
                    throw new Exception("该零件存在更早的库存条码");
                }
                dataList.add(inventoryDO);
            }
        }

        return dataList;
    }

    /**
     * @Author: WangKe
     * @Description: 在入库时根据条码查找零件
     * @Date: 2018/3/7 0007
     */
    @Transactional(rollbackFor = Exception.class)
    public List<WarehouseInventoryVO> findByBarCodeForInbound(String barCode, String businessOrder, String userId, String orgId) throws Exception {
        BarcodeManageDO barcodeDO = barcodeManageMapper.item(barCode, orgId);
        List<BarcodeManageDO> barcodeManageDOList = new ArrayList<>();
        if (barcodeDO == null) {
            //下游直接使用上游条码入库时，需要输入业务单号
            if (StringUtil.isNullOrEmpty(businessOrder)) {
                throw new Exception("请输入业务单号");
            }
            //下游直接使用上游条码入库时，复制条码
            barcodeManageDOList = this.copyBarcode(barCode, businessOrder, userId, orgId);
        } else {
            if (!StringUtil.isNullOrEmpty(businessOrder)) {
                WarehouseInboundDO inboundDO = warehouseInboundMapper.selectByOrder(businessOrder, orgId);
                if (inboundDO == null) {
                    throw new Exception("业务单号不正确");
                }
            }

            if (barcodeDO.getBarcodeFlag() == 0) { //总条码时查询分条码列表
                barcodeManageDOList.addAll(barcodeManageMapper.findBarcodeForInbound(barCode, orgId));
                if (ListUtil.isNullOrEmpty(barcodeManageDOList)) {
                    throw new Exception("该总条码下没有可入库的分条码");
                }
            } else {
                barcodeManageDOList.add(barcodeDO);
            }
        }
        if(barcodeDO!=null){
            if(priMaterialsMapper.itemByNo(barcodeDO.getMaterialsNo(),barcodeDO.getOrgId())==null){
                String supplierOrgId=barcodeManageMapper.findSupplierOrgId(barcodeDO.getBarcode(),barcodeDO.getOrgId());
                if(!StringUtil.isNullOrEmpty(supplierOrgId))
                {
                    materialsService.saveByInbound(barcodeDO.getMaterialsNo(), orgId, supplierOrgId);
                }
            }
        }

        if(barcodeDO!=null && barcodeDO.getBarcodeStatus().equals(BarcodeStatus.Status.OutStorage.toString())){
            //判读区域调拨单是否用出库的条码入库的
            checkRegionAllot(barCode, businessOrder, orgId);
        }
        //分条码不能同时出现已出库状态和已打印状态
        int num1 = 0;
        int num2 = 0;
        for (BarcodeManageDO barcodeManageDO : barcodeManageDOList) {
            if ("0".equals(barcodeManageDO.getBarcodeStatus())) {
                num1++;
            }
            if ("2".equals(barcodeManageDO.getBarcodeStatus())) {
                num2++;
            }
        }
        if (num1 > 0 && num2 > 0) {
            throw new Exception("分条码状态不一致，请扫描分条码");
        }
        for (BarcodeManageDO barcodeManageDO : barcodeManageDOList) {
            if (StringUtil.isNullOrEmpty(businessOrder) && !"0".equals(barcodeManageDO.getBarcodeStatus())) {
                throw new Exception("请输入业务单号");
            }
        }
        List<WarehouseInventoryVO> dataList = new ArrayList<>();
        String locationCode = "";
        boolean findLocation = true;
        for (BarcodeManageDO barcodeManageDO : barcodeManageDOList) {
            WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
            inventoryVO.setMaterialNo(barcodeManageDO.getMaterialsNo());
            inventoryVO.setMaterialName(barcodeManageDO.getMaterialsDes());
            inventoryVO.setAmount(barcodeManageDO.getCurrentQty());
            inventoryVO.setBarCode(barcodeManageDO.getBarcode());
            inventoryVO.setBarcodeStatus(barcodeManageDO.getBarcodeStatus());
            inventoryVO.setOrgId(barcodeManageDO.getOrgId());
            if ("0".equals(barcodeManageDO.getBarcodeStatus())) {
                inventoryVO.setBusinessOrder(barcodeManageDO.getBillNo());
            } else {
                inventoryVO.setBusinessOrder(businessOrder);
            }
            if (!StringUtil.isNullOrEmpty(locationCode)) {
                inventoryVO.setPriorLocationCode(locationCode);
                dataList.add(inventoryVO);
                continue;
            }
            //查找同类零件之前入库时存放的储位
            //先查找零件绑定的储位
            WarehouseInboundDO inboundDO = warehouseInboundMapper.selectByOrder(inventoryVO.getBusinessOrder(), orgId);
            if (inboundDO == null) {
                dataList.add(inventoryVO);
                continue;
            }
            locationCode = getLocationCode(orgId, barcodeManageDO.getMaterialsNo(), inboundDO.getWarehouseCode(), inboundDO.getBusinessOrder(),inboundDO.getInArea());
            inventoryVO.setPriorLocationCode(locationCode);
            if (CompanyUtil.isWJ(orgId) && findLocation) {
                findLocation = false;
                inventoryVO.setLocationCodeList(warehouseInventoryMapper.findLocationCode(orgId, inventoryVO.getMaterialNo(), inboundDO.getWarehouseCode(), inboundDO.getInArea()));
            }
            dataList.add(inventoryVO);
        }
        return dataList;
    }

    private boolean checkRegionAllot(String barcode, String businessOrder, String orgId) throws Exception {
        if (StringUtil.isNullOrEmpty(businessOrder) || !businessOrder.startsWith(BillDesc.RegionAllot.getDesc())) {
            return true;
        }
        List<WarehouseDeliveryRecordDO> list = warehouseDeliveryRecordMapper.findByBarcode(barcode, orgId);
        if (ListUtil.isNullOrEmpty(list)) {
            throw new Exception("ExportUtil调拨单已出库的条码入库");
        }
        boolean flag = false;
        for (WarehouseDeliveryRecordDO recordDO : list) {
            if (recordDO.getBusinessOrder().equals(businessOrder)) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            throw new Exception("只能用区域调拨单已出库的条码入库");
        }
        return true;
    }

    private String getLocationCode(String orgId, String materialsNo, String warehouseCode, String businessOrder,String areaCode) {
        String locationCode = null;
        locationCode = warehouseInventoryMapper.findInventoryLocationCode(materialsNo, warehouseCode, orgId,areaCode);
        if (!StringUtil.isNullOrEmpty(locationCode)) {
            return locationCode;
        }
        if (!CompanyUtil.isWJ(orgId)) {
            MaterialLocationRelationDO relationDO = materialLocationRelationMapper.findDefaultLocation(materialsNo, warehouseCode,areaCode, orgId);
            if (relationDO != null) {
                locationCode = relationDO.getLocationCode();
            }
            return locationCode;
        }
        return locationCode;
    }

    /**
     * @Author: WangKe
     * @Description: 下游直接使用上游条码入库时，复制条码
     * @Date: 2018/4/3 0003
     */
    private List<BarcodeManageDO> copyBarcode(String barCode, String businessOrder, String userId, String orgId) throws Exception {
        WarehouseInboundDO inboundDO = warehouseInboundMapper.selectByOrder(businessOrder, orgId);
        if (inboundDO == null) {
            throw new Exception("业务单号不正确");
        }
        List<BarcodeManageDO> barcodeManageDOList = barcodeManageMapper.itemByBarcode(barCode);
        if (ListUtil.isNullOrEmpty(barcodeManageDOList)) {
            throw new Exception("未能根据条码找到相关记录");
        }
        BarcodeManageDO barcodeManageDO = barcodeManageDOList.get(0);
        barcodeManageDOList = new ArrayList<>();
        if (barcodeManageDO.getBarcodeFlag() == 0) { //总条码时查询分条码列表
            barcodeManageDOList.add(barcodeManageDO);
            barcodeManageDOList.addAll(barcodeManageMapper.findByTotalBarcode(barCode, barcodeManageDO.getOrgId()));
        } else {
            if ("3".equals(barcodeManageDO.getBarcodeStatus())) {
                throw new Exception("条码已拆分");
            }
            barcodeManageDOList.add(barcodeManageDO);
        }
        if (ListUtil.isNullOrEmpty(barcodeManageDOList)) {
            throw new Exception("未能根据条码找到相关记录");
        }
        int num = 0;
        for (BarcodeManageDO barcode : barcodeManageDOList) {
            if (barcode.getBarcodeFlag() == 1 && "2".equals(barcode.getBarcodeStatus())) {
                num++;
            }
        }
        if (num == 0) {
            throw new Exception("未能根据条码找到相关记录，请确认上游条码是否已经出库");
        }

        //判断是否进出口运单入库，进出口入库需将采购合同号保存
        CompanyInfoVO companyInfoVO = companyInfoService.info(orgId);
        String purchaseContractNo = "";
        String machineModel = "";
        String country = "";
        String materialsDesEn = "";
        //进出口
        if (CompanyUtil.JCK_SAP_CODE.equals(companyInfoVO.getSapCode())){
            //根据入库单号查询信息
            if (businessOrder.startsWith(BillDesc.ReceiptIn.getDesc())){//运单入库
                ReceiptInDO receiptInDO = receiptInMapper.findByBillNo(businessOrder);
                DeliveryReceiptDO deliveryReceiptDO = deliveryReceiptMapper.itemByNo(receiptInDO.getReceiptNo());
                if (null != deliveryReceiptDO ){
                    if (StringUtils.isNotEmpty(deliveryReceiptDO.getPurchaseContractNo())){
                        purchaseContractNo = deliveryReceiptDO.getPurchaseContractNo();
                    }else{
                        throw new Exception("发运交接单中采购合同号不能为空");
                    }
                    if (StringUtils.isNotEmpty(deliveryReceiptDO.getCountry())){
                        country = deliveryReceiptDO.getCountry();
                    }
                }
                //查询发运交接单零件中零件机型
                DeliveryReceiptMaterialDO materialDO = deliveryReceiptMaterialMapper.findByMaterialNo(deliveryReceiptDO.getBillNo(),barcodeManageDO.getMaterialsNo());
                if (null != materialDO && StringUtils.isNotEmpty(materialDO.getMachineModel())){
                    machineModel = materialDO.getMachineModel();
                }

                //查询零件英文描述
                List<PubMaterialsDO> pubMaterialsDOS = pubMaterialsMapper.selectByMaterialsNos(Lists.newArrayList(barcodeManageDO.getMaterialsNo()));
                if (CollectionUtils.isNotEmpty(pubMaterialsDOS)) {
                    materialsDesEn = pubMaterialsDOS.get(0).getMaterialsDesEn();
                }
            }
        }


        boolean success;
        List<BarcodeManageDO> dataList = new ArrayList<>();
        for (BarcodeManageDO barcode : barcodeManageDOList) {
            if (barcode.getBarcodeFlag() == 1 && !"2".equals(barcode.getBarcodeStatus())) {
                continue;
            }
            if (barcodeManageMapper.item(barcode.getBarcode(), orgId) != null) {
                continue;
            }
            String copySourceOrgId = barcode.getOrgId();//复制的条码的来源公司
            //条码追踪需求，如果源条码时前移条码，copy新条码的时候需要判断如果源条码已经存在源公司和源条码则把对应字段值进行拷贝，
            // 如果不存在则把源条码的条码值和所属组织机构赋值给新条码的源公司和源条码字段
            forwardBarcodeExtend(barcode,copySourceOrgId);

            DataDictionaryDO detaildataDictionaryDO = dataDictionaryMapper.itemByCode(BarcodeStatus.Status.Name.toString(), "0");
            barcode.setOrgId(orgId);
            barcode.setBillNo(businessOrder);
            if(barcodeManageDO.getBarcodeFlag() != 0) {
                barcode.setBarcodeStatus("2");
            }
            if (detaildataDictionaryDO != null) {
                barcode.setStatusDesc(detaildataDictionaryDO.getName());
            }
            barcode.setCreateId(userId);
            barcode.setCreateName(commonService.getUserName(userId));
            barcode.setCreateTime(new Date());
            barcode.setPrintId(userId);
            barcode.setPrintName(barcode.getCreateName());
            barcode.setPrintTime(barcode.getCreateTime());
            barcode.setRowNo(null);

            //进出口
            if (CompanyUtil.JCK_SAP_CODE.equals(companyInfoVO.getSapCode())){
                barcode.setPurchaseContractNo(purchaseContractNo);
                barcode.setMachineModel(machineModel);
                barcode.setCountry(country);
                barcode.setMaterialsDesEn(materialsDesEn);
            }

            success = barcodeManageMapper.insert(barcode) > 0;
            if (!success) {
                throw new Exception("操作失败");
            }
            if (barcode.getBarcodeFlag() == 1) {
                dataList.add(barcode);
            }
        }
        return dataList;
    }

    //条码追踪需求，如果源条码时前移条码，copy新条码的时候需要判断如果源条码已经存在源公司和源条码则把对应字段值进行拷贝，
    // 如果不存在则把源条码的条码值和所属组织机构赋值给新条码的源公司和源条码字段
    private void forwardBarcodeExtend(BarcodeManageDO barcode,String copySourceOrgId) {
        Integer forward = barcode.getForward();
        if(forward == null || forward.compareTo(ForwardBarcodeLableEnum.FORWARD_BARCODE.getLable()) != 0){
            return ;
        }
        String forwardBarcodeOrigOrgid = barcode.getForwardBarcodeOrigOrgid();
        String forwardBarcodeOrigCode = barcode.getForwardBarcodeOrigCode();
        if(StringUtils.isEmpty(forwardBarcodeOrigOrgid) || StringUtils.isEmpty(forwardBarcodeOrigCode)){
            barcode.setForwardBarcodeOrigOrgid(copySourceOrgId);
            barcode.setForwardBarcodeOrigCode(barcode.getBarcode());
        }
    }


    /**
     * @Author: WangKe
     * @Description: 在零件入库时更新库存，新增或者更新
     * @Date: 2018/1/23 0023
     */
    public boolean saveByInbound(WarehouseInboundRecordDO warehouseInboundRecordDO, BigDecimal cost, String userId) {
        if (warehouseInboundRecordDO == null) {
            return false;
        }
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode()) {
            return false;
        }
        WarehouseInventoryDO warehouseInventoryDO = warehouseInventoryMapper.selectByBarCode(warehouseInboundRecordDO.getBarCode(), warehouseInboundRecordDO.getOrgId());
        if (warehouseInventoryDO != null) {
            if (warehouseInventoryDO.getIsOut() == 1) {
                warehouseInventoryDO.setIsOut(0);
                if (!warehouseInboundRecordDO.getLocationCode().equals(warehouseInventoryDO.getLocationCode())) {
                    warehouseInventoryDO.setLocationCode(warehouseInboundRecordDO.getLocationCode());
                    warehouseInventoryDO.setAreaCode(warehouseInboundRecordDO.getAreaCode());
                    warehouseInventoryDO.setWarehouseCode(warehouseInboundRecordDO.getWarehouseCode());
                }
                warehouseInventoryDO.setAmount(warehouseInboundRecordDO.getAmount());
            } else {
                warehouseInventoryDO.setAmount(warehouseInventoryDO.getAmount().add(warehouseInboundRecordDO.getAmount()));
            }
            warehouseInventoryDO.setLastChangeUser(userId);
            warehouseInventoryDO.setLastChangeDate(new Date());
            return warehouseInventoryMapper.updateByPrimaryKeySelective(warehouseInventoryDO) > 0;
        }
        warehouseInventoryDO = new WarehouseInventoryDO();
        BeanUtils.copyProperties(warehouseInboundRecordDO, warehouseInventoryDO);
        warehouseInventoryDO.setId(textResult.getValue());
        warehouseInventoryDO.setLastChangeUser(userId);
        warehouseInventoryDO.setLastChangeDate(new Date());
        warehouseInventoryDO.setCreaterId(userId);
        warehouseInventoryDO.setStatus(warehouseInboundRecordDO.getFrozen());
        warehouseInventoryDO.setIsOut(0);

        //计算成本
        if (cost != null) {
            BigDecimal v1 = warehouseInboundRecordDO.getAmount();
            BigDecimal v2 = v1.multiply(cost);
            warehouseInventoryDO.setCost(cost);
            warehouseInventoryDO.setTotalCost(v2);
        }

        return warehouseInventoryMapper.insert(warehouseInventoryDO) > 0;
    }

    /**
     * @Author: WangKe
     * @Description: 无条码管理零件入库时更新库存表
     * @Date: 2018/4/4 0004
     */
    public boolean updateByInboundWithNoBarcode(WarehouseInboundRecordDO warehouseInboundRecordDO, String userId, String orgId) throws Exception {
        if (warehouseInboundRecordDO == null) {
            return false;
        }
        WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
        inventoryVO.setOrgId(orgId);
        inventoryVO.setMaterialNo(warehouseInboundRecordDO.getMaterialNo());
        inventoryVO.setLocationCode(warehouseInboundRecordDO.getLocationCode());
        List<WarehouseInventoryDO> inventoryDOList = warehouseInventoryMapper.list(inventoryVO);
        if (ListUtil.isNullOrEmpty(inventoryDOList)) {
            //库存表中没有此零件，则新增
            WarehouseInventoryDO warehouseInventoryDO = new WarehouseInventoryDO();
            BeanUtils.copyProperties(warehouseInboundRecordDO, warehouseInventoryDO);
            warehouseInventoryDO.setStatus(0);
            warehouseInventoryDO.setIsOut(0);
            warehouseInventoryDO.setLastChangeUser(warehouseInventoryDO.getCreaterId());
            warehouseInventoryDO.setLastChangeDate(new Date());

            return warehouseInventoryMapper.insert(warehouseInventoryDO) > 0;
        } else {
            //库存表中有此零件，则增加数量
            WarehouseInventoryDO inventoryDO = inventoryDOList.get(0);
            inventoryDO.setAmount(inventoryDO.getAmount().add(warehouseInboundRecordDO.getAmount()));
            inventoryDO.setLastChangeUser(userId);
            inventoryDO.setLastChangeDate(new Date());
            return warehouseInventoryMapper.updateByPrimaryKeySelective(inventoryDO) > 0;
        }
    }

    /**
     * @Author: WangKe
     * @Description: 零件出库时在库存表保存相关记录
     * @Date: 2018/1/23 0023
     */
    public boolean saveByOutbound(WarehouseInventoryDO warehouseInventoryDO, WarehouseDeliveryRecordDO warehouseDeliveryRecordVO, String userId) {
        if (warehouseInventoryDO == null || warehouseDeliveryRecordVO == null) {
            return false;
        }
        warehouseInventoryDO.setLastChangeUser(userId);
        warehouseInventoryDO.setLastChangeDate(new Date());
        warehouseInventoryDO.setIsOut(1);
        return warehouseInventoryMapper.updateByPrimaryKeySelective(warehouseInventoryDO) > 0;
    }

    /**
     * @Author: WangKe
     * @Description: 无条码管理零件出库时更新库存表
     * @Date: 2018/4/8 0008
     */
    public boolean updateByOutboundNoBarcode(WarehouseDeliveryRecordDO deliveryRecordDO, String userId, String orgId) throws Exception {
        if (deliveryRecordDO == null) {
            return false;
        }
        WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
        inventoryVO.setOrgId(orgId);
        inventoryVO.setMaterialNo(deliveryRecordDO.getMaterialNo());
        inventoryVO.setLocationCode(deliveryRecordDO.getLocationCode());
        inventoryVO.setIsOut(0);
        List<WarehouseInventoryDO> inventoryDOList = warehouseInventoryMapper.list(inventoryVO);
        if (ListUtil.isNullOrEmpty(inventoryDOList)) {
            throw new Exception("库存表中未找到此零件，" + deliveryRecordDO.getMaterialNo() + "，请检查储位是否正确");
        }
        WarehouseInventoryDO inventoryDO = inventoryDOList.get(0);
        if (inventoryDO.getAmount().compareTo(deliveryRecordDO.getAmount()) < 0) {
            throw new Exception("库存表中此零件数量不足，" + deliveryRecordDO.getMaterialNo() + "，剩余" + inventoryDO.getAmount() + inventoryDO.getUnit());
        }
        inventoryDO.setAmount(inventoryDO.getAmount().subtract(deliveryRecordDO.getAmount()));
        inventoryDO.setLastChangeUser(userId);
        inventoryDO.setLastChangeDate(new Date());
        return warehouseInventoryMapper.updateByPrimaryKeySelective(inventoryDO) > 0;
    }

    public void update(WarehouseInventoryDO warehouseInventoryDO) {
        warehouseInventoryMapper.updateByPrimaryKeySelective(warehouseInventoryDO);
    }

    /**
     * @Author: WangKe
     * @Description: 查看库存列表
     * @Date: 2018/1/23 0023
     */
    public PageCommonVO list(SearchCommonVO<WarehouseInventoryVO> condition,String departmentId) {
        PageCommonVO<WarehouseInventoryVO> pageCommonVO = new PageCommonVO();
        //获取当前部门是否添加仓库权限
        boolean warehousePermission = getWarehousePermission(condition, departmentId, pageCommonVO);
        if (warehousePermission) {
            return pageCommonVO;
        }
        WarehouseInventoryVO conditionVO = condition.getFilters();

        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize(), "a.material_no");
        if (!StringUtil.isNullOrEmpty(conditionVO.getMaterialName())) {
            conditionVO.setMaterialName(conditionVO.getMaterialName().replaceAll("\\s+", ""));
        }
        List<WarehouseInventoryVO> voList = new ArrayList<WarehouseInventoryVO>();
        List<WarehouseInventoryDO> doList = null;
        if (!StringUtil.isNullOrEmpty(conditionVO.getLocationCode())) {
            String locationCode = conditionVO.getLocationCode();
            if (locationCode.toCharArray()[0] == '\uFEFF') {
                locationCode = locationCode.substring(1);
            }
            conditionVO.setLocationCode(locationCode);
        }
        conditionVO.setMaterialsList(xcmg.device.infra.StringUtil.splitList(conditionVO.getMaterialsNos()));
        conditionVO = fillLocationInfo(conditionVO);

//        condition.getFilters().setLocationCodeList(filterLocationCode(condition.getFilters().getLocationCodes()));
        doList = warehouseInventoryMapper.listWithKeeper(condition.getFilters());
        List<String> warehouseCodes=new ArrayList<>();
        Map<String,BigDecimal> warehouseMap=new HashMap<>();
        for (WarehouseInventoryDO entity : doList) {
            if(warehouseMap.size()>0 && warehouseMap.containsKey(entity.getWarehouseCode()+"|" + entity.getMaterialNo())){
                if(entity.getAmount().compareTo(warehouseMap.get(entity.getWarehouseCode()+"|" + entity.getMaterialNo()))>0){
                    entity.setDeliveryNum(warehouseMap.get(entity.getWarehouseCode()+"|" + entity.getMaterialNo()));
                    warehouseMap.put((entity.getWarehouseCode()+"|" + entity.getMaterialNo()),new BigDecimal(0));
                }else {
                    entity.setDeliveryNum(entity.getAmount());
                    BigDecimal surplus=warehouseMap.get(entity.getWarehouseCode()+"|" + entity.getMaterialNo()).subtract(entity.getAmount());
                    warehouseMap.put((entity.getWarehouseCode()+"|" + entity.getMaterialNo()),surplus);
                }
            }else {
                if(entity.getAmount().compareTo(entity.getDeliveryNum())>0){
                    warehouseMap.put((entity.getWarehouseCode()+"|" + entity.getMaterialNo()),new BigDecimal(0));
                }else {
                    BigDecimal surplus=entity.getDeliveryNum().subtract(entity.getAmount());
                    warehouseMap.put((entity.getWarehouseCode()+"|" + entity.getMaterialNo()),surplus);
                    entity.setDeliveryNum(entity.getAmount());
                }
            }
                entity.setEnableNum(entity.getAmount().subtract(entity.getDeliveryNum()));
            WarehouseInventoryVO model = new WarehouseInventoryVO();
            BeanUtils.copyProperties(entity, model);
            voList.add(model);
        }
        //添加仓库描述
        Map<String,String> warehouseCache=new HashMap<>();
        for (WarehouseInventoryVO vo : voList) {
            if (StringUtils.isNotBlank(vo.getWarehouseCode()) && StringUtils.isNotBlank(vo.getOrgId())) {
                String desc = warehouseCache.get(vo.getWarehouseCode() + "_" + vo.getOrgId());
                if (null != desc) {
                    vo.setWarehouseDesc(desc);
                } else {
                    WarehouseDO warehouse = warehouseDOMapper.itemByWarehouseCode(vo.getOrgId(), vo.getWarehouseCode());
                    if (null != warehouse) {
                        vo.setWarehouseDesc(warehouse.getDescription());
                        warehouseCache.put(vo.getWarehouseCode() + "_" + vo.getOrgId(), warehouse.getDescription());
                    }
                }
            }
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    /**
     * 给个默认的拥有所有权限
     */
    private static final String FULL_PERMISSION_DEPT = "admin";

    private boolean getWarehousePermission(SearchCommonVO<WarehouseInventoryVO> condition, String departmentId, PageCommonVO<WarehouseInventoryVO> pageCommonVO) {

        if (FULL_PERMISSION_DEPT.equals(departmentId)) {
            return false;
        }
        boolean exist = relationService.verifyThatPermissionsExist(departmentId, condition.getFilters().getOrgId());
        if (exist){
            List<String> warehouseList = relationService.getWarehouse(departmentId, condition.getFilters().getOrgId());
            if (warehouseList.isEmpty()){
                pageCommonVO.setPageInfo(new PageInfo(new ArrayList()));
                pageCommonVO.setPageInfoList(new ArrayList<>());
                return true;
            }
            condition.getFilters().setWarehousePermitList(warehouseList);
        }
        return false;
    }

    private List<String> filterLocationCode(String locationCodes) {
        List<String> list = xcmg.device.infra.StringUtil.splitList(locationCodes);
        if (!ListUtil.isNullOrEmpty(list)) {
            for (String str : list) {
                if (str.toCharArray()[0] == '\uFEFF') {
                    str = str.substring(1);
                }
            }
        }
        return list;
    }

    /**
     * @Author: WangKe
     * @Description: 查看库存详情列表
     * @Date: 2018/1/23 0023
     */
    public PageCommonVO detailList(SearchCommonVO<WarehouseInventoryVO> condition) {
        PageCommonVO<WarehouseInventoryVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.orderBy("CREATE_DATE ASC");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        if (!StringUtil.isNullOrEmpty(condition.getFilters().getMaterialName())) {
            condition.getFilters().setMaterialName(condition.getFilters().getMaterialName().replaceAll("\\s+", ""));
        }
        if (!StringUtil.isNullOrEmpty(condition.getFilters().getLocationCode())) {
            String locationCode = condition.getFilters().getLocationCode();
            if (locationCode.toCharArray()[0] == '\uFEFF') {
                locationCode = locationCode.substring(1);
            }
            if (locationCode.contains(",")) {
                condition.getFilters().setLocationCode(null);
                String[] locationCodes=locationCode.split(",");
                condition.getFilters().setLocationCodeList(Arrays.asList(locationCodes));
            }else {
                condition.getFilters().setLocationCode(locationCode);
            }
        }
        condition.getFilters().setIsOut(0);
        List<WarehouseInventoryDO> doList = warehouseInventoryMapper.listForMaterialDetail(condition.getFilters());
        List<WarehouseInventoryVO> voList = new ArrayList<WarehouseInventoryVO>();
        for (WarehouseInventoryDO entity : doList) {
            WarehouseInventoryVO model = new WarehouseInventoryVO();
            BeanUtils.copyProperties(entity, model);
            voList.add(model);
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    /**
     * @Author: WangKe
     * @Description: 查看库存详情列表
     * @Date: 2018/1/23 0023
     */
    public PageCommonVO listForCollect(SearchCommonVO<WarehouseInventoryVO> condition) {
        PageCommonVO<WarehouseInventoryVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.orderBy("MATERIAL_NO ASC");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        if (!StringUtil.isNullOrEmpty(condition.getFilters().getMaterialName())) {
            condition.getFilters().setMaterialName(condition.getFilters().getMaterialName().replaceAll("\\s+", ""));
        }
        if (!StringUtil.isNullOrEmpty(condition.getFilters().getLocationCode())) {
            String locationCode = condition.getFilters().getLocationCode();
            if (locationCode.toCharArray()[0] == '\uFEFF') {
                locationCode = locationCode.substring(1);
            }
            condition.getFilters().setLocationCode(locationCode);
        }
        condition.getFilters().setIsOut(0);
        List<WarehouseInventoryDO> doList = warehouseInventoryMapper.listForCollect(condition.getFilters());
        List<WarehouseInventoryVO> voList = new ArrayList<WarehouseInventoryVO>();
        for (WarehouseInventoryDO entity : doList) {
            WarehouseInventoryVO model = new WarehouseInventoryVO();
            BeanUtils.copyProperties(entity, model);
            voList.add(model);
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    /**
     * @Author: WangKe
     * @Description: 根据主键查找实体
     * @Date: 2018/1/23 0023
     */
    public WarehouseInventoryVO findByPK(String id) {
        WarehouseInventoryDO entity = warehouseInventoryMapper.selectByPrimaryKey(id);
        if (entity == null) {
            return null;
        }
        WarehouseInventoryVO WarehouseInventoryVO = new WarehouseInventoryVO();
        BeanUtils.copyProperties(entity, WarehouseInventoryVO);
        return WarehouseInventoryVO;
    }

    /**
     * @Author: WangKe
     * @Description: 根据主键列表删除库存记录
     * @Date: 2018/1/26 0026
     */
    public ErrorCode remove(List<String> ids) {
        return warehouseInventoryMapper.remove(ids) > 0 ? ErrorCode.Success : ErrorCode.WarehouseIdError;
    }

    /**
     * @Author: WangKe
     * @Description: 根据总条码进行零件转移
     * @Date: 2018/3/16 0016
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode batchTransferByMaterial(WarehouseInventoryBatchTransferVO batchTransferVO, String userId, String orgId) throws Exception {
        if (ListUtil.isNullOrEmpty(batchTransferVO.getRecordList())) {
            return ErrorCode.IllegalArument;
        }
        if (warehouseInventoryMapper.locationCodeCount(batchTransferVO) > 1) {
            return ErrorCode.MaterialsLocationDifferent;
        }
        ErrorCode errorCode = ErrorCode.Success;
        List<WarehouseInventoryDO> inventoryDOList = new ArrayList<>();
        for (int i = 0; i < batchTransferVO.getRecordList().size(); i++) {
            try {
                errorCode = this.transferByMaterial(batchTransferVO.getRecordList().get(i), inventoryDOList, orgId, userId);
            } catch (Exception e) {
                throw new Exception("index&&" + i + "&&" + e.getMessage());
            }
            if (errorCode.getCode() != 0) {
                throw new Exception("index&&" + i + "&&" + errorCode.getDesc());
            }
        }
        boolean success = this.addTransferRecord(inventoryDOList, userId, orgId);
        if (!success) {
            throw new Exception("生成转库单失败");
        }
        return errorCode;
    }

    /**
     * @Author: WangKe
     * @Description: 根据条码和新储位进行零件转移
     * @Date: 2018/2/28 0028
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode transferByMaterial(WarehouseInventoryTransferVO transferVO, List<WarehouseInventoryDO> inventoryDOList, String orgId, String userId) throws Exception {
        WarehouseInventoryDO inventoryDO = warehouseInventoryMapper.selectByBarCode(transferVO.getBarCode(), orgId);
        if (inventoryDO == null) {
            return ErrorCode.IllegalArument;
        }
        if (inventoryDO.getLocationCode().toCharArray()[0] == '\uFEFF') {
            inventoryDO.setLocationCode(inventoryDO.getLocationCode().substring(1));
        }
        String locationCode = transferVO.getNewLocationCode();
        if (locationCode.toCharArray()[0] == '\uFEFF') {
            locationCode = locationCode.substring(1);
        }
        Map<String, Object> warehouseMap = warehouseAreaLocationDOMapper.findAllCode(locationCode, orgId);
        if (warehouseMap == null || warehouseMap.get("WAREHOUSE_CODE") == null || warehouseMap.get("AREA_CODE") == null) {
            return ErrorCode.WarehouseLocationCodeError;
        }

        if (inventoryDO.getLocationCode().equals(transferVO.getNewLocationCode())) {
            return ErrorCode.MustBeNewLocation;
        }

        if (inventoryDO.getIsOut() == 1) {
            return ErrorCode.Failure;
        }

        String areaCode = (String) warehouseMap.get("AREA_CODE");
        if (CompanyUtil.isWJ(orgId) && !StringUtils.equals(inventoryDO.getAreaCode(), areaCode)) {
            throw new Exception("不允许跨库区转移储位");
        }
        String warehouseCode = (String) warehouseMap.get("WAREHOUSE_CODE");
        inventoryDO.setOldLocationCode(inventoryDO.getLocationCode());
        inventoryDO.setWarehouseCode(warehouseCode);
        inventoryDO.setAreaCode(areaCode);
        inventoryDO.setLocationCode(transferVO.getNewLocationCode());
        inventoryDO.setSapAreaCode((String) warehouseMap.get("SAP_CODE"));
        inventoryDO.setLastChangeDate(new Date());
        inventoryDO.setLastChangeUser(userId);

        boolean success = warehouseInventoryMapper.updateByPrimaryKeySelective(inventoryDO) > 0;
        if (success) {
            //更新相关入库记录
//            WarehouseInboundRecordDO inboundRecordDO = warehouseInboundRecordMapper.findByBarcode(transferVO.getBarCode(), orgId);
//            if (inboundRecordDO != null) {
//                inboundRecordDO.setWarehouseCode(inventoryDO.getWarehouseCode());
//                inboundRecordDO.setAreaCode(inventoryDO.getAreaCode());
//                inboundRecordDO.setLocationCode(inventoryDO.getLocationCode());
//
//                success = warehouseInboundRecordMapper.updateByPrimaryKeySelective(inboundRecordDO) > 0;
//                if (!success) {
//                    throw new Exception("更新相关入库记录失败");
//                }
//            }

            inventoryDOList.add(inventoryDO);
        }
        if(!success){
            return ErrorCode.Failure;
        }
        //默认储位逻辑处理
        boolean changeLocationRelation = transferVO.isChangeLocationRelation();
        String materialNo = inventoryDO.getMaterialNo();
        success = transferLocationRelationHandle(userId,changeLocationRelation, transferVO.getNewLocationCode(), orgId, warehouseCode,areaCode, materialNo);
        return success ? ErrorCode.Success : ErrorCode.Failure;
    }

    /**
     * @Des 零件转移默认储位处理
     * @Date 2021/3/9 14:06
     * @Author wangzhaoyu
     * @Param [changeLocationRelation, newLocationCode]
     * @Return void
     */
    private boolean transferLocationRelationHandle(String userId,boolean changeLocationRelation,String newLocationCode,String orgId,String warehouseCode,String areaCode,String materialsNo) {
        //如果不更新则直接跳出方法
        if(!changeLocationRelation){
            return true;
        }
        //存在不满足条件的则直接跳出方法
        if(StringUtils.isEmpty(newLocationCode) || StringUtils.isEmpty(orgId)
                || StringUtils.isEmpty(warehouseCode) || StringUtils.isEmpty(materialsNo)
                || StringUtils.isEmpty(areaCode)){
            return true;
        }
        //查询是否零件在该仓库是否已经存在默认储位，
        // 如果不存在则进行新增操作，
        // 如果存在则对比存在的默认储位和新传入的储位是否为同一个储位，如果时同一个储位则不处理，如果储位不同则删除原来的默认储位，新增本次传入的默认储位
        MaterialLocationRelationVO condition = new MaterialLocationRelationVO();
        condition.setWarehouseCode(warehouseCode);
        condition.setMaterialNo(materialsNo);
        condition.setOrgId(orgId);
        List<MaterialLocationRelationVO> relationVOList = materialLocationRelationMapper.list(condition);
        if(CollectionUtils.isEmpty(relationVOList)){//新增默认储位
            return addLocationRelation(userId,newLocationCode,orgId,warehouseCode,areaCode,materialsNo);
        }else{//更新默认储位
            boolean newLocationCodeExisted = false;
            for(MaterialLocationRelationVO materialLocationRelation : relationVOList){
                String locationCode = materialLocationRelation.getLocationCode();
                if(!StringUtils.isEmpty(locationCode) && locationCode.equals(newLocationCode)){
                    newLocationCodeExisted = true;
                    break;
                }
            }
            if(!newLocationCodeExisted){
                //删除原本存在的默认储位，添加新的默认储位
                for(MaterialLocationRelationVO materialLocationRelation : relationVOList){
                    String id = materialLocationRelation.getId();
                    materialLocationRelationMapper.deleteByPrimaryKey(id);
                }
                return addLocationRelation(userId,newLocationCode,orgId,warehouseCode,areaCode,materialsNo);
            }
            return true;
        }
    }

    public boolean addLocationRelation(String userId,String newLocationCode,String orgId,String warehouseCode,String areaCode,String materialsNo){
        MaterialLocationRelationDO relationDO = new MaterialLocationRelationDO();
        relationDO.setId(fastGenClient.textGuid().getValue());
        relationDO.setMaterialNo(materialsNo);
        relationDO.setWarehouseCode(warehouseCode);
        relationDO.setAreaCode(areaCode);
        relationDO.setLocationCode(newLocationCode);
        relationDO.setOrgId(orgId);
        relationDO.setCreateDate(new Date());
        relationDO.setCreateId(userId);
        relationDO.setCreateName(commonService.getUserName(userId));
        return materialLocationRelationMapper.insert(relationDO) > 0;
    }


    private boolean addTransferRecord(List<WarehouseInventoryDO> inventoryDOList, String userId, String orgId) throws Exception {
        MaterialTransferAddVO transferAddVO = new MaterialTransferAddVO();
        MaterialTransferVO transferVO = new MaterialTransferVO();
        List<MaterialTransferDetailVO> transferDetailVOList = new ArrayList<>();

        WarehouseInventoryDO inventoryDO = inventoryDOList.get(0);
        Map<String, Object> oldWarehouseMap = warehouseAreaLocationDOMapper.findAllCode(inventoryDO.getOldLocationCode(), orgId);
        if (oldWarehouseMap == null || oldWarehouseMap.get("WAREHOUSE_CODE") == null || oldWarehouseMap.get("AREA_CODE") == null) {
            throw new Exception("储位编码错误");
        }
        transferVO.setType(0);
        transferVO.setPreLocationCode(inventoryDO.getOldLocationCode());
        transferVO.setPreAreaCode((String) oldWarehouseMap.get("AREA_CODE"));
        transferVO.setPreSapArea((String) oldWarehouseMap.get("SAP_CODE"));
        transferVO.setPreWarehouseCode((String) oldWarehouseMap.get("WAREHOUSE_CODE"));
        transferVO.setNewLocationCode(inventoryDO.getLocationCode());
        transferVO.setNewAreaCode(inventoryDO.getAreaCode());
        transferVO.setNewSapArea(inventoryDO.getSapAreaCode());
        transferVO.setNewWarehouseCode(inventoryDO.getWarehouseCode());
        transferVO.setOrgId(orgId);

        for (WarehouseInventoryDO inventory : inventoryDOList) {
            MaterialTransferDetailVO transferDetailVO = new MaterialTransferDetailVO();
            BeanUtils.copyProperties(inventory, transferDetailVO);
            transferDetailVO.setBarcode(inventory.getBarCode());
            transferDetailVOList.add(transferDetailVO);
        }
        transferAddVO.setHeaderInfo(transferVO);
        transferAddVO.setDetailList(transferDetailVOList);
        return materialTransferService.addPre(transferAddVO, userId, orgId).getCode() == 0;
    }

    /**
     * @Author: WangKe
     * @Description: 根据新储位和旧储位进行零件转移
     * @Date: 2018/3/1 0001
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode transferByLocation(String oldLocationCode, String newLocationCode, String orgId, String userId) throws Exception {
        if (oldLocationCode.toCharArray()[0] == '\uFEFF') {
            oldLocationCode = oldLocationCode.substring(1);
        }
        Map<String, Object> oldWarehouseMap = warehouseAreaLocationDOMapper.findAllCode(oldLocationCode, orgId);
        if (oldWarehouseMap == null || oldWarehouseMap.get("WAREHOUSE_CODE") == null || oldWarehouseMap.get("AREA_CODE") == null) {
            return ErrorCode.WarehouseLocationCodeError;
        }
        if (newLocationCode.toCharArray()[0] == '\uFEFF') {
            newLocationCode = newLocationCode.substring(1);
        }
        Map<String, Object> newWarehouseMap = warehouseAreaLocationDOMapper.findAllCode(newLocationCode, orgId);
        if (newWarehouseMap == null || newWarehouseMap.get("WAREHOUSE_CODE") == null || newWarehouseMap.get("AREA_CODE") == null) {
            return ErrorCode.WarehouseLocationCodeError;
        }

        WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
        inventoryVO.setOrgId(orgId);
        inventoryVO.setLocationCode((String) oldWarehouseMap.get("LOCATION_CODE"));
        inventoryVO.setIsOut(0);
        List<WarehouseInventoryDO> inventoryDOList = warehouseInventoryMapper.list(inventoryVO);
        if (ListUtil.isNullOrEmpty(inventoryDOList)) {
            throw new Exception(oldWarehouseMap.get("LOCATION_CODE") + "，该储位下未找到零件");
        }

        WarehouseInventoryDO inventoryDO = new WarehouseInventoryDO();
        inventoryDO.setWarehouseCode((String) newWarehouseMap.get("WAREHOUSE_CODE"));
        inventoryDO.setAreaCode((String) newWarehouseMap.get("AREA_CODE"));
        inventoryDO.setLocationCode(newLocationCode);
        inventoryDO.setLastChangeDate(new Date());
        inventoryDO.setLastChangeUser(userId);
        inventoryDO.setOldLocationCode(oldLocationCode);
        inventoryDO.setOrgId(orgId);

        boolean success = warehouseInventoryMapper.updateByLocation(inventoryDO) > 0;
        if (success) {
            //更新相关入库记录
//            WarehouseInboundRecordDO inboundRecordDO = new WarehouseInboundRecordDO();
//            inboundRecordDO.setWarehouseCode(inventoryDO.getWarehouseCode());
//            inboundRecordDO.setAreaCode(inventoryDO.getAreaCode());
//            inboundRecordDO.setLocationCode(inventoryDO.getLocationCode());
//            inboundRecordDO.setOldLocationCode(oldLocationCode);
//            inboundRecordDO.setOrgId(orgId);
//
//            success = warehouseInboundRecordMapper.updateByLocation(inboundRecordDO) > 0;
//            if (!success) {
//                throw new Exception("更新相关入库记录失败");
//            }

            success = this.addTransferRecord(oldWarehouseMap, newWarehouseMap, inventoryDOList, userId, orgId);
            if (!success) {
                throw new Exception("生成转库单失败");
            }
        }
        return success ? ErrorCode.Success : ErrorCode.Failure;
    }

    private boolean addTransferRecord(Map<String, Object> oldWarehouseMap, Map<String, Object> newWarehouseMap, List<WarehouseInventoryDO> inventoryDOList, String userId, String orgId) throws Exception {
        MaterialTransferAddVO transferAddVO = new MaterialTransferAddVO();
        MaterialTransferVO transferVO = new MaterialTransferVO();
        List<MaterialTransferDetailVO> transferDetailVOList = new ArrayList<>();

        transferVO.setType(1);
        transferVO.setPreLocationCode((String) oldWarehouseMap.get("LOCATION_CODE"));
        transferVO.setPreAreaCode((String) oldWarehouseMap.get("AREA_CODE"));
        transferVO.setPreSapArea((String) oldWarehouseMap.get("SAP_CODE"));
        transferVO.setPreWarehouseCode((String) oldWarehouseMap.get("WAREHOUSE_CODE"));
        transferVO.setNewLocationCode((String) newWarehouseMap.get("LOCATION_CODE"));
        transferVO.setNewAreaCode((String) newWarehouseMap.get("AREA_CODE"));
        transferVO.setNewSapArea((String) newWarehouseMap.get("SAP_CODE"));
        transferVO.setNewWarehouseCode((String) newWarehouseMap.get("WAREHOUSE_CODE"));
        transferVO.setOrgId(orgId);

        for (WarehouseInventoryDO inventory : inventoryDOList) {
            MaterialTransferDetailVO transferDetailVO = new MaterialTransferDetailVO();
            BeanUtils.copyProperties(inventory, transferDetailVO);
            transferDetailVO.setBarcode(inventory.getBarCode());
            transferDetailVOList.add(transferDetailVO);
        }
        transferAddVO.setHeaderInfo(transferVO);
        transferAddVO.setDetailList(transferDetailVOList);
        return materialTransferService.addPre(transferAddVO, userId, orgId).getCode() == 0;
    }

    /**
     * @Author: WangKe
     * @Description: 查询出入库记录
     * @Date: 2018/3/2 0002
     */
    public PageCommonVO listForInOutRecord(SearchCommonVO<WarehouseInOutBaseVO> condition) {


        WarehouseInOutBaseVO conditionVO = condition.getFilters();

        conditionVO.getBusinessOrder();


        PageCommonVO<WarehouseInOutBaseVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        conditionVO.setMaterialsList(xcmg.device.infra.StringUtil.splitList(conditionVO.getMaterialsNos()));
        conditionVO.setLocationCodeList(filterLocationCode(conditionVO.getLocationCodes()));
        List<WarehouseInOutBaseDO> doList = warehouseInboundRecordMapper.findAllInOut(conditionVO);
        List<WarehouseInOutBaseVO> voList = new ArrayList<WarehouseInOutBaseVO>();
        //添加仓库描述
        Map<String,String> warehouseCache=new HashMap<>();
        for (WarehouseInOutBaseDO entity : doList) {
            WarehouseInOutBaseVO model = new WarehouseInOutBaseVO();
            BeanUtils.copyProperties(entity, model);
            //如果是装箱出库类型的数据，零件原数量置为1（参照随车）
            if (StringUtils.equals("XGZX",model.getBusinessSingle())) {
                model.setTotalAmount(BigDecimal.ONE);
            }
            if (StringUtils.isNotBlank(model.getWarehouseCode()) && StringUtils.isNotBlank(model.getOrgId())) {
                String desc = warehouseCache.get(model.getWarehouseCode() + "_" + model.getOrgId());
                if (null != desc) {
                    model.setWarehouseDesc(desc);
                } else {
                    WarehouseDO warehouse = warehouseDOMapper.itemByWarehouseCode(model.getOrgId(), model.getWarehouseCode());
                    if (null != warehouse) {
                        model.setWarehouseDesc(warehouse.getDescription());
                        warehouseCache.put(model.getWarehouseCode() + "_" + model.getOrgId(), warehouse.getDescription());
                    }
                }
            }
            voList.add(model);
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;

    }
    
    public List<WarehouseInOutBaseVO> listForInOutRecordNotPackaged(WarehouseInOutBaseVO conditionVO) throws Exception {

        conditionVO.setMaterialsList(xcmg.device.infra.StringUtil.splitList(conditionVO.getMaterialsNos()));
        conditionVO.setLocationCodeList(filterLocationCode(conditionVO.getLocationCodes()));
        List<WarehouseInOutBaseDO> doList = warehouseInboundRecordMapper.findAllInOutNotPackaged(conditionVO);
        List<WarehouseInOutBaseVO> voList = new ArrayList<WarehouseInOutBaseVO>();
        //添加仓库描述
        Map<String,String> warehouseCache=new HashMap<>();
        for (WarehouseInOutBaseDO entity : doList) {
            WarehouseInOutBaseVO model = new WarehouseInOutBaseVO();
            BeanUtils.copyProperties(entity, model);
            //如果是装箱出库类型的数据，零件原数量置为1（参照随车）
            if (StringUtils.equals("XGZX",model.getBusinessSingle())) {
                model.setTotalAmount(BigDecimal.ONE);
            }
            voList.add(model);
        }
        return voList;

    }
    
    public PageCommonVO listForInOutRecordGroup(SearchCommonVO<WarehouseInOutBaseVO> condition) {

        WarehouseInOutBaseVO conditionVO = condition.getFilters();

        conditionVO.getBusinessOrder();

        PageCommonVO<WarehouseInOutBaseVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        conditionVO.setMaterialsList(xcmg.device.infra.StringUtil.splitList(conditionVO.getMaterialsNos()));
        conditionVO.setLocationCodeList(filterLocationCode(conditionVO.getLocationCodes()));
        List<WarehouseInOutBaseDO> doList = warehouseInboundRecordMapper.findAllInOutGroup(conditionVO);
        List<WarehouseInOutBaseVO> voList = new ArrayList<WarehouseInOutBaseVO>();
        //添加仓库描述
        Map<String,String> warehouseCache=new HashMap<>();
        for (WarehouseInOutBaseDO entity : doList) {
            WarehouseInOutBaseVO model = new WarehouseInOutBaseVO();
            BeanUtils.copyProperties(entity, model);
            if (StringUtils.isNotBlank(model.getWarehouseCode()) && StringUtils.isNotBlank(model.getOrgId())) {
                String desc = warehouseCache.get(model.getWarehouseCode() + "_" + model.getOrgId());
                if (null != desc) {
                    model.setWarehouseDesc(desc);
                } else {
                    WarehouseDO warehouse = warehouseDOMapper.itemByWarehouseCode(model.getOrgId(), model.getWarehouseCode());
                    if (null != warehouse) {
                        model.setWarehouseDesc(warehouse.getDescription());
                        warehouseCache.put(model.getWarehouseCode() + "_" + model.getOrgId(), warehouse.getDescription());
                    }
                }
            }
            voList.add(model);
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;

    }

    /**
     * @Author: WangKe
     * @Description: 批量更新条码冻结状态
     * @Date: 2018/3/16 0016
     */
    public FunctionResult batchUpdateFrozenState(WarehouseInventoryBatchFrozenVO batchFrozenVO, String orgId) {
        FunctionResult result = new FunctionResult();
        if (ListUtil.isNullOrEmpty(batchFrozenVO.getRecordList())) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("参数错误");
            return result;
        }
        List<WarehouseInventoryFrozenVO> errorList = new ArrayList<>();
        ErrorCode errorCode = ErrorCode.Failure;
        for (WarehouseInventoryFrozenVO recordAddVO : batchFrozenVO.getRecordList()) {
            try {
                errorCode = this.updateFrozenState(recordAddVO, orgId);
            } catch (Exception e) {
                recordAddVO.setRemark(e.getMessage());
                errorList.add(recordAddVO);
            }
            if (errorCode.getCode() != 0) {
                recordAddVO.setRemark(errorCode.getDesc());
                errorList.add(recordAddVO);
            }
        }
        if (ListUtil.isNullOrEmpty(errorList)) {
            result.setCode(ErrorCode.Success);
            result.setValue(ErrorCode.Success.getDesc());
        } else {
            result.setCode(ErrorCode.Failure);
            result.setValue(errorList);
        }
        return result;
    }

    /**
     * @Author: WangKe
     * @Description: 更新库存零件冻结状态
     * @Date: 2018/3/8 0008
     */
    public ErrorCode updateFrozenState(WarehouseInventoryFrozenVO frozenVO, String orgId) {
        WarehouseInventoryDO inventoryDO = warehouseInventoryMapper.selectByBarCode(frozenVO.getBarCode(), orgId);
        if (inventoryDO == null || inventoryDO.getStatus() > 1) {
            return ErrorCode.IllegalArument;
        }
        inventoryDO.setStatus(frozenVO.getState());
        return warehouseInventoryMapper.updateByPrimaryKeySelective(inventoryDO) > 0 ? ErrorCode.Success : ErrorCode.Failure;
    }

    /**
     * @Author: WangKe
     * @Description: 根据零件编码获取零件可用库存，意向占用库存，发货占用库存
     * @Date: 2018/3/19 0019
     */
    public EnableAndOccupyVO findEnableAndOccupyNum(String materialNo, String orgId, String warehouseCode) {
        EnableAndOccupyVO enableAndOccupyVO = new EnableAndOccupyVO();
        enableAndOccupyVO.setEnableNum(warehouseInventoryMapper.findEnableNum(materialNo, orgId, warehouseCode));
//        enableAndOccupyVO.setDeliveryNum(warehouseDeliveryDetailMapper.findOccupyNum(materialNo, orgId, warehouseCode));
//        enableAndOccupyVO.setIntentionNum(saleIntentionDetailMapper.findOccupyNum(materialNo, orgId));
        enableAndOccupyVO.setDeliveryNum(BigDecimal.ZERO);
        enableAndOccupyVO.setIntentionNum(BigDecimal.ZERO);
        return enableAndOccupyVO;
    }


    public EnableAndOccupyVO findEnableAndOccupyNum2(String materialNo, String orgId, String warehouseCode,Map<String,BigDecimal> ynIn) {
        EnableAndOccupyVO enableAndOccupyVO = new EnableAndOccupyVO();
        if (companyUtil.isYN(orgId)) {
            BigDecimal d = ynIn.get(materialNo);
            if (null != d) {
                enableAndOccupyVO.setEnableNum(d);
            } else {
                enableAndOccupyVO.setEnableNum(BigDecimal.ZERO);
            }
        } else {
            enableAndOccupyVO.setEnableNum(warehouseInventoryMapper.findEnableNum(materialNo, orgId, warehouseCode));
        }
//        enableAndOccupyVO.setDeliveryNum(warehouseDeliveryDetailMapper.findOccupyNum(materialNo, orgId, warehouseCode));
//        enableAndOccupyVO.setIntentionNum(saleIntentionDetailMapper.findOccupyNum(materialNo, orgId));
        enableAndOccupyVO.setDeliveryNum(BigDecimal.ZERO);
        enableAndOccupyVO.setIntentionNum(BigDecimal.ZERO);
        return enableAndOccupyVO;
    }

    /**
     * 塔机库存校验
     * @param findMaterialsNumParam
     * @return
     */
    public boolean tjFindMaterialsNum(FindMaterialsNumParam findMaterialsNumParam)
    {
        List<FindMaterialsInfos> materialsInfos=findMaterialsNumParam.getMaterialsNos();
        if(CollectionUtils.isEmpty(materialsInfos)){
            return true;
        }
        List<List<FindMaterialsInfos>> subList=splitList(materialsInfos,500);
        List<FindMaterialsNumVO> findMaterialsNumVOList=new ArrayList<>();
        for (List<FindMaterialsInfos> infos : subList){
            findMaterialsNumParam.setMaterialsNos(infos);
            List<FindMaterialsNumVO>findMaterialsNumVOS=warehouseInventoryMapper.findMaterialsNum(findMaterialsNumParam);
            findMaterialsNumVOList.addAll(findMaterialsNumVOS);
        }
        for (FindMaterialsInfos infos:materialsInfos) {
            for (FindMaterialsNumVO nums:findMaterialsNumVOList) {
                if(infos.getMaterialsNo().equals(nums.getMaterialsNo())){
                    if(nums.getEnableNum().compareTo(nums.getDeliveryNum().add(infos.getAmount()))<0){
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /**
     * 库存校验（铲运）
     * @param findMaterialsNumParam
     * @return
     */
    public boolean cyFindMaterialsNum(FindMaterialsNumParam findMaterialsNumParam)
    {
        List<FindMaterialsInfos> materialsInfos = findMaterialsNumParam.getMaterialsNos();
        if(CollectionUtils.isEmpty(materialsInfos)){
            return true;
        }

        //集合拆分
        List<List<FindMaterialsInfos>> subList = Lists.partition(materialsInfos,500);
        List<FindMaterialsNumVO> findMaterialsNumVOList = new ArrayList<>();
        for (List<FindMaterialsInfos> infos : subList){
            findMaterialsNumParam.setMaterialsNos(infos);
            //查询零件总库存和在运库存
            List<FindMaterialsNumVO> findMaterialsNumVOS = warehouseInventoryMapper.findMaterialsNum(findMaterialsNumParam);
            findMaterialsNumVOList.addAll(findMaterialsNumVOS);
        }
        //校验库存是否足够
        for (FindMaterialsInfos infos : materialsInfos) {
            for (FindMaterialsNumVO nums : findMaterialsNumVOList) {
                if(infos.getMaterialsNo().equals(nums.getMaterialsNo())){
                    if(nums.getEnableNum().compareTo(nums.getDeliveryNum().add(infos.getAmount()))<0){
                        return false;
                    }
                }
            }
        }
        return true;
    }

    public boolean findMaterialsNum(FindMaterialsNumParam findMaterialsNumParam)
    {
        if(!CompanyUtil.isWJ(findMaterialsNumParam.getOrgId())){
            return true;
        }
        List<FindMaterialsInfos> materialsInfos=findMaterialsNumParam.getMaterialsNos();
        if(CollectionUtils.isEmpty(materialsInfos)){
            return true;
        }
        List<List<FindMaterialsInfos>> subList=splitList(materialsInfos,500);
        List<FindMaterialsNumVO> findMaterialsNumVOList=new ArrayList<>();
        for (List<FindMaterialsInfos> infos : subList){
            findMaterialsNumParam.setMaterialsNos(infos);
            List<FindMaterialsNumVO>findMaterialsNumVOS=warehouseInventoryMapper.findMaterialsNum(findMaterialsNumParam);
            findMaterialsNumVOList.addAll(findMaterialsNumVOS);
        }
        for (FindMaterialsInfos infos:materialsInfos) {
            for (FindMaterialsNumVO nums:findMaterialsNumVOList) {
                if(infos.getMaterialsNo().equals(nums.getMaterialsNo())){
                    if(nums.getEnableNum().compareTo(nums.getDeliveryNum().add(infos.getAmount()))<0){
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private List<List<FindMaterialsInfos>> splitList(List<FindMaterialsInfos> list, int len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<FindMaterialsInfos>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<FindMaterialsInfos> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }
    /**
     * 储位支持单个模糊/多个精确搜索
     *
     * @param condition
     * @return
     */
    private WarehouseInventoryVO fillLocationInfo(WarehouseInventoryVO condition) {
        if (StringUtils.isNotBlank(condition.getLocationCodes())) {
            List<String> locationList = xcmg.device.infra.StringUtil.getStrSplitList(condition.getLocationCodes());
            if (locationList.size() > 1) {
                condition.setLocationCodeList(locationList);
            } else {
                condition.setLocationCodeLike(locationList.get(0));
                condition.setLocationCodes(null);
            }
        }
        return condition;
    }

    /**
     * @Author: WangKe
     * @Description: 导出全部库存列表
     * @Date: 2018/3/19 0019
     */
    public void exportAll(WarehouseInventoryVO condition, String title) throws Exception {
        if (stringRedisTemplate.hasKey(INVENTORY_EXPORT)) {
            return;
        }
        List<WarehouseInventoryDO> dataList = new ArrayList<>();
        try {
            stringRedisTemplate.opsForValue().set(INVENTORY_EXPORT, "1", 600, TimeUnit.SECONDS);
            if (!StringUtil.isNullOrEmpty(condition.getMaterialName())) {
                condition.setMaterialName(condition.getMaterialName().replaceAll("\\s+", ""));
            }
            condition.setMaterialsList(xcmg.device.infra.StringUtil.splitList(condition.getMaterialsNos()));
            condition = fillLocationInfo(condition);
//            condition.setLocationCodeList(filterLocationCode(condition.getLocationCodes()));

            Integer count = warehouseInventoryMapper.findCountForExportAllKeeper(condition);
            int times = count / 1000 + 1;
            for (int i = 0; i < times; i++) {
                PageHelperPlus.startPage(i + 1, 1000, "c.SHELF_NO,to_number(c.ROW_NO),to_number(c.FLOOR_NO),to_number(c.COLUMN_NO),to_number(c.SEQ_NO),a.MATERIAL_NO");
                dataList.addAll(warehouseInventoryMapper.listWithKeeperForExport(condition));
            }
        } catch (Exception e) {
            LogHelper.error(e.getMessage(), ErrorCode.Failure.getCode());
        } finally {
            stringRedisTemplate.delete(INVENTORY_EXPORT);
        }
        warehouseInvokeExport(dataList, title);
    }

    /**
     * @Author: WangKe
     * @Description: 导出库存列表
     * @Date: 2018/3/19 0019
     */
    private void invokeExport(List<WarehouseInventoryDO> doList, String title) throws Exception {
        String[] rowsName = new String[]{"序号", "客户名称", "零件编码", "零件名称", "零件分类", "仓库编码",
                "库区", "储位", "库存数量", "可用库存","计量单位", "库存类型", "保管员", "仓库描述"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs;
        List<String> warehouseCodes=new ArrayList<>();
        for (int i = 0; i < doList.size(); i++) {
            WarehouseInventoryDO exportDO = doList.get(i);
            if(warehouseCodes.size()>0 && warehouseCodes.contains(exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo())){
                exportDO.setEnableNum(exportDO.getAmount().subtract(new BigDecimal(0)));
            }else {
                warehouseCodes.add(exportDO.getWarehouseCode() +"|" + exportDO.getMaterialNo());
            }
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = exportDO.getCompanyName();
            objs[2] = exportDO.getMaterialNo();
            objs[3] = exportDO.getMaterialName();
            objs[4] = exportDO.getMaterialType();
            objs[5] = exportDO.getWarehouseCode();
            objs[6] = exportDO.getAreaCode();
            objs[7] = exportDO.getLocationCode();
            objs[8] = exportDO.getAmount();
            objs[9] = exportDO.getEnableNum();
            objs[10] = exportDO.getUnit();
            objs[11] = getState(exportDO.getStatus());
            objs[12] = exportDO.getKeeper();
            objs[13] = exportDO.getWarehouseName();

            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private void warehouseInvokeExport(List<WarehouseInventoryDO> doList, String title) throws Exception {
        String[] rowsName = new String[]{"序号", "客户名称", "零件编码", "零件名称", "零件分类", "仓库编码",
                "库区", "储位", "库存数量", "可用库存", "发货占用","意向占用","计量单位", "库存类型", "保管员"};
        List<Object[]> dataList = new ArrayList<>();
        Object[] objs;
        List<String> warehouseCodes=new ArrayList<>();
        Map<String,BigDecimal> warehouseMap=new HashMap<>();
        for (int i = 0; i < doList.size(); i++) {
            WarehouseInventoryDO exportDO = doList.get(i);
            if(warehouseMap.size()>0 && warehouseMap.containsKey(exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo())){
                if(exportDO.getAmount().compareTo(warehouseMap.get(exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo()))>0){
                    exportDO.setDeliveryNum(warehouseMap.get(exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo()));
                    warehouseMap.put((exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo()),new BigDecimal(0));
                }else {
                    exportDO.setDeliveryNum(exportDO.getAmount());
                    BigDecimal surplus=warehouseMap.get(exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo()).subtract(exportDO.getAmount());
                    warehouseMap.put((exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo()),surplus);
                }
            }else {
                if(exportDO.getAmount().compareTo(exportDO.getDeliveryNum())>0){
                    warehouseMap.put((exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo()),new BigDecimal(0));
            }else {
                    BigDecimal surplus=exportDO.getDeliveryNum().subtract(exportDO.getAmount());
                    warehouseMap.put((exportDO.getWarehouseCode()+"|" + exportDO.getMaterialNo()),surplus);
                    exportDO.setDeliveryNum(exportDO.getAmount());
                }
            }
            exportDO.setEnableNum(exportDO.getAmount().subtract(exportDO.getDeliveryNum()));

            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = exportDO.getCompanyName();
            objs[2] = exportDO.getMaterialNo();
            objs[3] = exportDO.getMaterialName();
            objs[4] = exportDO.getMaterialType();
            objs[5] = exportDO.getWarehouseCode();
            objs[6] = exportDO.getAreaCode();
            objs[7] = exportDO.getLocationCode();
            objs[8] = exportDO.getAmount();
            objs[9] = exportDO.getEnableNum();
            objs[10] = exportDO.getDeliveryNum();
            objs[11] = exportDO.getIntentionNum();
            objs[12] = exportDO.getUnit();
            objs[13] = getState(exportDO.getStatus());
            objs[14] = exportDO.getKeeper();

            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    public String getState(Integer state) {
        if (state == 0) {
            return "正常库存";
        } else if (state == 1) {
            return "冻结库存";
        } else if (state == 2) {
            return "非正常库存";
        } else if (state == 3) {
            return "借用";
        } else if (state == 4) {
            return "已拆分";
        }
        return "";
    }

    /**
     * @Author: WangKe
     * @Description: 部分导出出入库记录列表
     * @Date: 2018/3/22 0022
     */
    public void exportForInOutRecord(List<String> ids) throws Exception {
        WarehouseInOutBaseVO inOutBaseVO = new WarehouseInOutBaseVO();
        inOutBaseVO.setIds(ids);
        invokeExportForInOutRecord(warehouseInboundRecordMapper.findAllInOut(inOutBaseVO));
    }

    /**
     * @Author: WangKe
     * @Description: 全部导出出入库记录列表
     * @Date: 2018/3/22 0022
     */
    public void exportAllForInOutRecord(WarehouseInOutBaseVO condition) throws Exception {
        condition.setMaterialsList(xcmg.device.infra.StringUtil.splitList(condition.getMaterialsNos()));
        condition.setLocationCodeList(filterLocationCode(condition.getLocationCodes()));
        //Integer count = warehouseInboundRecordMapper.findCountForAllInOut(condition);
        List<WarehouseInOutBaseDO> dataList = warehouseInboundRecordMapper.findAllInOut(condition);
//        int times = count / 500 + 1;
//        for (int i = 0; i < times; i++) {
//            PageHelperPlus.startPage(i + 1, 500);
//            dataList.addAll(warehouseInboundRecordMapper.findAllInOut(condition));
//        }
        invokeExportForInOutRecord(dataList);
    }


    public void exportAllForInOutRecordGroup(WarehouseInOutBaseVO condition) throws Exception {
        condition.setMaterialsList(xcmg.device.infra.StringUtil.splitList(condition.getMaterialsNos()));
        condition.setLocationCodeList(filterLocationCode(condition.getLocationCodes()));
        //Integer count = warehouseInboundRecordMapper.findCountForAllInOut(condition);
        List<WarehouseInOutBaseDO> dataList = warehouseInboundRecordMapper.findAllInOutGroup(condition);
//        int times = count / 500 + 1;
//        for (int i = 0; i < times; i++) {
//            PageHelperPlus.startPage(i + 1, 500);
//            dataList.addAll(warehouseInboundRecordMapper.findAllInOut(condition));
//        }
        invokeExportForInOutRecordGroup(dataList);
    }


    private void invokeExportForInOutRecord(List<WarehouseInOutBaseDO> doList) throws Exception {
        String title = "出入库记录导出";
        String[] rowsName = new String[]{"序号", "业务单号", "条形码", "零件号", "零件名称",
                "仓库编码", "库区", "储位", "操作数量", "计量单位", "操作时间", "创建人", "出入库类型", "出入库描述"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < doList.size(); i++) {
            WarehouseInOutBaseDO exportDO = doList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = exportDO.getBusinessOrder();
            objs[2] = exportDO.getBarCode();
            objs[3] = exportDO.getMaterialNo();
            objs[4] = exportDO.getMaterialName();
            objs[5] = exportDO.getWarehouseCode();
            objs[6] = exportDO.getAreaCode();
            objs[7] = exportDO.getLocationCode();
            objs[8] = exportDO.getAmount();
            objs[9] = exportDO.getUnit();
            objs[10] = sdf.format(exportDO.getCreateDate());
            objs[11] = exportDO.getCreaterName();
            objs[12] = exportDO.getBusinessSingle();
            objs[13] = getDesc(exportDO.getBusinessSingle());
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private void invokeExportForInOutRecordGroup(List<WarehouseInOutBaseDO> doList) throws Exception {
        String title = "出入库记录汇总导出";
        String[] rowsName = new String[]{"序号", "业务单号", "零件号", "零件名称",
                "仓库编码", "库区", "操作数量", "计量单位", "操作时间", "创建人", "出入库类型", "出入库描述"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < doList.size(); i++) {
            WarehouseInOutBaseDO exportDO = doList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = exportDO.getBusinessOrder();
            objs[2] = exportDO.getMaterialNo();
            objs[3] = exportDO.getMaterialName();
            objs[4] = exportDO.getWarehouseCode();
            objs[5] = exportDO.getAreaCode();
            objs[6] = exportDO.getAmount();
            objs[7] = exportDO.getUnit();
            objs[8] = exportDO.getCreateDateStr();
            objs[9] = exportDO.getCreaterName();
            objs[10] = exportDO.getBusinessSingle();
            objs[11] = getDesc(exportDO.getBusinessSingle());
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private String getDesc(String businessSingle) {
        switch (businessSingle) {
            case "XGFR":
                return "其它入库";
            case "XGFT":
                return "发货通知";
            case "XGFC":
                return "其它出库";
            case "XGLL":
                return "领料单";
            case "XGQD":
                return "区域调拨";
            case "XGDB":
                return "代理商间调拨";
            case "XGCX":
                return "冲销入库";
            case "XGTH":
                return "退货入库";
            case "XGSC":
                return "三包出库";
            case "XGCI":
                return "采购入库";
            case "XGQR":
                return "期初入库";
            case "XGPS":
                return "配送指令入库";
            case "XGHI":
                return "回购入库";
            case "XGCC":
                return "销售订单";
            case "XGSB":
                return "三包申请";
            case "XGJY":
                return "借用出库";
            case "XSCK":
                return "销售单出库";
            case "XGHO":
                return "回购出库";
            case "XGJI":
                return "借用退回入库";
            case "XSTH":
                return "退货单入库";
            default:
                return "其它";
        }
    }

    /**
     * @Author: WangKe
     * @Description: 手动创建预留单
     * @Date: 2018/4/18 0018
     */
    public ErrorCode manualCreateObligateOrder(String id, String businessOrder, String orgId) throws Exception {
        String realSapCode = sapCode;
        DataDictionaryDO dictionaryDO = dataDictionaryMapper.itemByCode(CompanyConstants.MID_WAREHOUSE_CODE, orgId);
        if (null != dictionaryDO && StringUtils.isNotBlank(dictionaryDO.getName())) {
            realSapCode = dictionaryDO.getName();
        }
        CompanyInfoVO companyInfoVO = companyInfoService.info(orgId);
        //判断当前企业是否调用sap接口
        if (companyInfoVO == null || companyInfoVO.getIsSap() == null || companyInfoVO.getIsSap() == 0) {
            return ErrorCode.SAPDisable;
        }
        if (StringUtil.isNullOrEmpty(id) || StringUtil.isNullOrEmpty(businessOrder) || businessOrder.length() < 4) {
            return ErrorCode.IllegalArument;
        }
        String businessSingle = businessOrder.substring(0, 4);
        List<ObligateVO> obligateVOList = new ArrayList<>();
        ObligateVO obligateVO;
        ObligateVO obligateVO2;
        ObligateHeaderVO headerVO = new ObligateHeaderVO();
        if (BillDesc.AbnoramlIn.getDesc().equals(businessSingle)) { //更新非正常入库单
            AbnormalInAddVO abnormalInAddVO = abnormalInService.findByPK(id, "id", orgId);
            if (abnormalInAddVO == null || ListUtil.isNullOrEmpty(abnormalInAddVO.getDetailList())) {
                throw new Exception("未找到其它入库单，请检查参数是否正确");
            }
            if (abnormalInAddVO.getHeaderInfo().getIsSynsap() != 1) {
                throw new Exception("此其它入库单不需要同步到SAP");
            }
            if (abnormalInAddVO.getHeaderInfo().getIsSynsapSuccess() != null && abnormalInAddVO.getHeaderInfo().getIsSynsapSuccess() == 1) {
                throw new Exception("请勿重复提交");
            }
            headerVO.setBusinesId(abnormalInAddVO.getHeaderInfo().getId());
            headerVO.setBusinesOrder(abnormalInAddVO.getHeaderInfo().getAbnormalNo());
            headerVO.setBusinesSingle(businessSingle);
            for (AbnormalInDetailVO detail : abnormalInAddVO.getDetailList()) {
                obligateVO = new ObligateVO();
                obligateVO.setMaterialNo(detail.getMaterialsNo());
                obligateVO.setAmount(detail.getQty());
                obligateVO.setInnerOrder(abnormalInAddVO.getHeaderInfo().getInnerOrder());
                obligateVO.setMoveType(abnormalInAddVO.getHeaderInfo().getMoveType());
                obligateVO.setWarehouseCode(abnormalInAddVO.getHeaderInfo().getInLocation());
                obligateVO.setSapInArea(abnormalInAddVO.getHeaderInfo().getSapInArea());
                //obligateVO.setSapOutArea(abnormalInAddVO.getHeaderInfo().getSapOutArea());
                obligateVOList.add(obligateVO);
            }
//            sapCommonService.createObligateOrder(headerVO, obligateVOList, null, orgId);
        } else if (BillDesc.AbnormalOutNo.getDesc().equals(businessSingle)) { //更新其他出库单
            AbnormalAddVO abnormalAddVO = abnormalOutService.item(id);
            if (abnormalAddVO == null || ListUtil.isNullOrEmpty(abnormalAddVO.getMaterialList())) {
                throw new Exception("未找到其他出库单，请检查参数是否正确");
            }
            if (abnormalAddVO.getHeaderInfo().getIsSynsap().intValue() != 1) {
                throw new Exception("此其他出库单不需要同步到SAP");
            }
            if (abnormalAddVO.getHeaderInfo().getIsSynsapSuccess() != null && abnormalAddVO.getHeaderInfo().getIsSynsapSuccess().equals(1)) {
                throw new Exception("请勿重复提交");
            }
            headerVO.setBusinesId(abnormalAddVO.getHeaderInfo().getId());
            headerVO.setBusinesOrder(abnormalAddVO.getHeaderInfo().getAbnormalNo());
            headerVO.setBusinesSingle(businessSingle);
            for (AbnormalOutDetailVO detail : abnormalAddVO.getMaterialList()) {
                obligateVO = new ObligateVO();
                obligateVO.setMaterialNo(detail.getMaterialsNo());
                obligateVO.setAmount(detail.getQty());
                obligateVO.setInnerOrder(abnormalAddVO.getHeaderInfo().getInnerOrder());
                obligateVO.setMoveType(abnormalAddVO.getHeaderInfo().getMoveType());
                obligateVO.setWarehouseCode(abnormalAddVO.getHeaderInfo().getOutLocation());
                //obligateVO.setSapInArea(abnormalAddVO.getHeaderInfo().getSapInArea());
                obligateVO.setSapOutArea(abnormalAddVO.getHeaderInfo().getSapOutArea());
                obligateVO.setGeneralLedgerCategory(abnormalAddVO.getHeaderInfo().getGeneralLedgerCategory());
                obligateVOList.add(obligateVO);
            }
//            sapCommonService.createObligateOrder(headerVO, obligateVOList, null, orgId);
        } else if (BillDesc.ThreeOut.getDesc().equals(businessSingle)) { //更新三包出库单
            ThreeGuaranteesOutAddVO threeGuaranteesOutAddVO = threeGuaranteesOutService.item(id);
            if (threeGuaranteesOutAddVO == null || ListUtil.isNullOrEmpty(threeGuaranteesOutAddVO.getDetailList())) {
                throw new Exception("未找到三包出库单，请检查参数是否正确");
            }
            if (threeGuaranteesOutAddVO.getHeaderInfo().getSapStatus() != null && threeGuaranteesOutAddVO.getHeaderInfo().getSapStatus() == 1) {
                throw new Exception("请勿重复提交");
            }
            headerVO.setBusinesId(threeGuaranteesOutAddVO.getHeaderInfo().getId());
            headerVO.setBusinesOrder(threeGuaranteesOutAddVO.getHeaderInfo().getGuaranteesOutNo());
            headerVO.setBusinesSingle(businessSingle);
            for (ThreeGuaranteesOutDetailVO detail : threeGuaranteesOutAddVO.getDetailList()) {
                obligateVO = new ObligateVO();
                obligateVO.setMaterialNo(detail.getMaterialsNo());
                obligateVO.setAmount(detail.getQty());
                obligateVO.setMoveType(threeGuaranteesOutAddVO.getHeaderInfo().getSapTypeName());
                obligateVO.setWarehouseCode(threeGuaranteesOutAddVO.getHeaderInfo().getOutLocation());
                //obligateVO.setSapInArea(abnormalAddVO.getHeaderInfo().getSapInArea());
                obligateVO.setSapOutArea(threeGuaranteesOutAddVO.getHeaderInfo().getSapOutArea());
                obligateVO.setInnerOrder(threeGuaranteesOutAddVO.getHeaderInfo().getSapId());
                obligateVOList.add(obligateVO);
            }
//            sapCommonService.createObligateOrder(headerVO, obligateVOList, null, orgId);
        } else if (BillDesc.RegionAllot.getDesc().equals(businessSingle)) { //更新区域调拨单
//            RegionAllotAddVO regionAllotAddVO = regionAllotService.findByPK(id, "id", orgId);
//            boolean sapNoPostOrg = sapCommonService.sapNoPostOrg(orgId);
//            if(sapNoPostOrg){
//                throw new Exception("不允许创建预留单");
//            }
//            if (regionAllotAddVO == null || ListUtil.isNullOrEmpty(regionAllotAddVO.getDetailList())) {
//                throw new Exception("未找到区域调拨单，请检查参数是否正确");
//            }
//            if (regionAllotAddVO.getHeaderInfo().getIsSynSap() != null && regionAllotAddVO.getHeaderInfo().getIsSynSap() == 1) {
//                throw new Exception("请勿重复提交");
//            }
//            List<ObligateVO> obligateVOList1 = new ArrayList<>();
//            List<ObligateVO> obligateVOList2 = new ArrayList<>();
//            for (RegionAllotDetailVO detailVO : regionAllotAddVO.getDetailList()) {
//                obligateVO = new ObligateVO();
//                obligateVO2 = new ObligateVO();
//                obligateVO.setMaterialNo(detailVO.getMaterialNo());
//                obligateVO.setAmount(detailVO.getAmount());
//                obligateVO.setMoveType(regionAllotAddVO.getHeaderInfo().getMoveType());
//                obligateVO.setWarehouseCode(regionAllotAddVO.getHeaderInfo().getOutLocation());
//                BeanUtils.copyProperties(obligateVO, obligateVO2);
//                obligateVO.setSapOutArea(regionAllotAddVO.getHeaderInfo().getSapOutArea());
//                obligateVO.setSapInArea(realSapCode);
//                obligateVOList1.add(obligateVO);
//
//                obligateVO2.setSapOutArea(realSapCode);
//                obligateVO2.setSapInArea(regionAllotAddVO.getHeaderInfo().getSapInArea());
//                obligateVOList2.add(obligateVO2);
//            }
//            headerVO.setBusinesId(regionAllotAddVO.getHeaderInfo().getId());
//            headerVO.setBusinesOrder(regionAllotAddVO.getHeaderInfo().getAllotOrder());
//            headerVO.setBusinesSingle(businessSingle);
//            sapCommonService.createObligateOrder(headerVO, obligateVOList1, obligateVOList2, orgId);
        } else if (BillDesc.MaterialsCode.getDesc().equals(businessSingle)) { //更新领料单
            MaterialsScheduleAddVO materialsScheduleAddVO = materialsScheduleService.item(id);
            if (materialsScheduleAddVO == null || ListUtil.isNullOrEmpty(materialsScheduleAddVO.getDetailList())) {
                throw new Exception("未找到领料单，请检查参数是否正确");
            }
            if (materialsScheduleAddVO.getHeaderInfo().getSapStatus() != null && materialsScheduleAddVO.getHeaderInfo().getSapStatus() == 1) {
                throw new Exception("请勿重复提交");
            }
            List<ObligateVO> obligateVOList1 = new ArrayList<>();
            List<ObligateVO> obligateVOList2 = new ArrayList<>();
            for (MaterialsScheduleDetailVO detailVO : materialsScheduleAddVO.getDetailList()) {
                obligateVO = new ObligateVO();
                obligateVO2 = new ObligateVO();
                obligateVO.setMaterialNo(detailVO.getMaterialsNo());
                obligateVO.setAmount(detailVO.getAmount());
                obligateVO.setMoveType(materialsScheduleAddVO.getHeaderInfo().getSapType());
                obligateVO.setWarehouseCode(materialsScheduleAddVO.getHeaderInfo().getOutLocation());
                BeanUtils.copyProperties(obligateVO, obligateVO2);
                if (materialsScheduleAddVO.getHeaderInfo().getType() == 1) {
                    obligateVO.setSapOutArea(materialsScheduleAddVO.getHeaderInfo().getSapOutArea());
                    obligateVO.setSapInArea(realSapCode);
                } else {
                    obligateVO.setSapOutArea(detailVO.getOutLocation());
                    obligateVO.setSapInArea(realSapCode);
                }
                obligateVOList1.add(obligateVO);
                if (materialsScheduleAddVO.getHeaderInfo().getType() == 1) {
                    obligateVO2.setSapOutArea(realSapCode);
                    obligateVO2.setSapInArea(materialsScheduleAddVO.getHeaderInfo().getInLocation());
                } else {
                    obligateVO2.setSapOutArea(realSapCode);
                    obligateVO2.setSapInArea(materialsScheduleAddVO.getHeaderInfo().getSapInArea());
                }
                obligateVOList2.add(obligateVO2);
            }
            headerVO.setBusinesId(materialsScheduleAddVO.getHeaderInfo().getId());
            headerVO.setBusinesOrder(materialsScheduleAddVO.getHeaderInfo().getRequisitionNo());
            headerVO.setBusinesSingle(businessSingle);
//            sapCommonService.createObligateOrder(headerVO, obligateVOList1, obligateVOList2, orgId);
        }
        return ErrorCode.Success;
    }

    /**
     * @Author: WangKe
     * @Description: 用于pda库存查询
     * @Date: 2018/7/27 0027
     */
    public List<WarehouseInventoryDO> listForPDA(SearchCommonVO<WarehouseInventoryVO> searchCommonVO, String userId,String departmentId) throws Exception {
        List<WarehouseInventoryDO> dataList = new ArrayList<>();
        //零件号查询，判断零件号和当前保管员账号是不是有绑定关系来进行过滤
       // listForPDAFilter(searchCommonVO.getFilters(), userId);

       //获取当前部门是否添加仓库权限
        boolean warehouseControl = checkWarehouseControl(searchCommonVO, departmentId);
        if (warehouseControl) {
            return dataList;
        }

        WarehouseInventoryVO inventoryVO = searchCommonVO.getFilters();
        PriMaterialsDO priMaterialsDO = null;
        if (!StringUtil.isNullOrEmpty(inventoryVO.getMaterialNo())) {
            priMaterialsDO = priMaterialsMapper.itemByNo(inventoryVO.getMaterialNo(), inventoryVO.getOrgId());
            if (priMaterialsDO == null) {
                throw new Exception("零件不存在");
            }
        }
        if (!StringUtil.isNullOrEmpty(inventoryVO.getBarCode())) {
            BarcodeManageDO barcodeManageDO = barcodeManageMapper.item(inventoryVO.getBarCode(), inventoryVO.getOrgId());
            if (barcodeManageDO == null) {
                throw new Exception("条码不存在");
            }
            if (barcodeManageDO.getBarcodeFlag() == 0) {
                throw new Exception("请输入分条码进行查询");
            }
            if (priMaterialsDO != null && !priMaterialsDO.getMaterialsNo().equals(barcodeManageDO.getMaterialsNo())) {
                return new ArrayList<>();
            }
        }
        PageHelperPlus.startPage(searchCommonVO.getPageNum(), searchCommonVO.getPageSize());
        List<WarehouseInventoryDO> inventoryDOList = warehouseInventoryMapper.listForPDA(inventoryVO);
        if (!ListUtil.isNullOrEmpty(inventoryDOList)) {
            return inventoryDOList;
        }
        if (priMaterialsDO == null) {
            throw new Exception("零件不存在");
        } else {
            MaterialLocationRelationVO condition = new MaterialLocationRelationVO();
            condition.setOrgId(inventoryVO.getOrgId());
            condition.setMaterialNo(inventoryVO.getMaterialNo());
            condition.setWarehousePermitList(inventoryVO.getWarehousePermitList());
            List<MaterialLocationRelationVO> relationVOList = materialLocationRelationMapper.list(condition);
            if (!ListUtil.isNullOrEmpty(relationVOList)) {
                for (MaterialLocationRelationVO relationVO : relationVOList) {
                    WarehouseInventoryDO temp = new WarehouseInventoryDO();
                    temp.setMaterialNo(priMaterialsDO.getMaterialsNo());
                    temp.setMaterialName(priMaterialsDO.getMaterialsDes());
                    temp.setMaterialType(priMaterialsDO.getMaterialsType());
                    temp.setLocationCode(relationVO.getLocationCode());
                    temp.setAmount(BigDecimal.ZERO);
                    dataList.add(temp);
                }
            } else {
                WarehouseInventoryDO temp = new WarehouseInventoryDO();
                temp.setMaterialNo(priMaterialsDO.getMaterialsNo());
                temp.setMaterialName(priMaterialsDO.getMaterialsDes());
                temp.setMaterialType(priMaterialsDO.getMaterialsType());
                temp.setAmount(BigDecimal.ZERO);
                dataList.add(temp);
            }
            return dataList;
        }
    }

    private boolean checkWarehouseControl(SearchCommonVO<WarehouseInventoryVO> searchCommonVO, String departmentId) {
        boolean exist = relationService.verifyThatPermissionsExist(departmentId, searchCommonVO.getFilters().getOrgId());
        if (exist){
            List<String> warehouseList = relationService.getWarehouse(departmentId, searchCommonVO.getFilters().getOrgId());
            if (warehouseList.isEmpty()){
                return true;
            }
            searchCommonVO.getFilters().setWarehousePermitList(warehouseList);
        }
        return false;
    }

    private void listForPDAFilter(WarehouseInventoryVO inventoryVO, String userId) throws Exception {
        if (!CompanyUtil.isWJ(inventoryVO.getOrgId())) {
            return;
        }
        if (StringUtil.isNullOrEmpty(inventoryVO.getMaterialNo())) {
            return;
        }
        List<String> list1 = materialWarehouseUserMapper.findByMaterialAndUserId(inventoryVO.getMaterialNo(), inventoryVO.getOrgId(), null);
        List<String> list2 = materialWarehouseUserMapper.findByMaterialAndUserId(null, inventoryVO.getOrgId(), userId);
        if (ListUtil.isNullOrEmpty(list1) || ListUtil.isNullOrEmpty(list2)) {
            throw new Exception("所查询零件为其他用户保管");
        }
        list1.retainAll(list2);
        if (ListUtil.isNullOrEmpty(list1)) {
            throw new Exception("所查询零件为其他用户保管");
        }
    }

    //判断是否有权限
    public CompanyDealerDO isStorage(String supplierOrgId, String orgId) {
        return companyDealerMapper.itemByOrgId(supplierOrgId, orgId);
    }

    public PageCommonVO enterpriseStockList(SearchCommonVO<WarehouseInventoryStockVO> condition,String departmentId) {
        WarehouseInventoryVO warehouseInventoryVO = new WarehouseInventoryVO();
        WarehouseInventoryStockVO warehouseInventoryStockVO = condition.getFilters();
        warehouseInventoryVO.setOrgId(warehouseInventoryStockVO.getOrgId());
        warehouseInventoryVO.setMaterialNo(warehouseInventoryStockVO.getMaterialNo());
        warehouseInventoryVO.setAreaCode(warehouseInventoryStockVO.getAreaCode());
        warehouseInventoryVO.setMaterialName(warehouseInventoryStockVO.getMaterialName());
        warehouseInventoryVO.setLocationCode(warehouseInventoryStockVO.getLocationCode());
        warehouseInventoryVO.setWarehouseCode(warehouseInventoryStockVO.getWarehouseCode());
        warehouseInventoryVO.setMaterialsType(warehouseInventoryStockVO.getMaterialType());
        warehouseInventoryVO.setMaterialsTypeId(warehouseInventoryStockVO.getMaterialsTypeId());
        SearchCommonVO searchCommonVO = new SearchCommonVO();
        searchCommonVO.setFilters(warehouseInventoryVO);
        searchCommonVO.setPageSize(condition.getPageSize());
        searchCommonVO.setPageNum(condition.getPageNum());
        searchCommonVO.setSort(condition.getSort());
        return list(searchCommonVO,departmentId);
    }

    public PageCommonVO listForQueryDetail(SearchCommonVO<WarehouseInventoryVO> condition) {
        PageCommonVO<WarehouseInventoryDO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize(), "create_date desc");
        List<WarehouseInventoryDO> voList = warehouseInventoryMapper.listForQueryDetail(condition.getFilters());
        pageCommonVO.setPageInfo(new PageInfo(voList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    public PageCommonVO intentionDetailList(SearchCommonVO<WarehoseIntentionDetialVO> condition) {
        PageCommonVO<WarehoseIntentionDetialVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<WarehoseIntentionDetialVO> voList = warehouseInventoryMapper.intentionDetailList(condition.getFilters());
        pageCommonVO.setPageInfo(new PageInfo(voList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    public PageCommonVO deliveryDetailList(SearchCommonVO<WarehoseIntentionDetialVO> condition) {
        PageCommonVO<WarehoseIntentionDetialVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<WarehoseIntentionDetialVO> voList = warehouseInventoryMapper.deliveryDetailList(condition.getFilters());
        pageCommonVO.setPageInfo(new PageInfo(voList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    public PageCommonVO listForDealer(SearchCommonVO<WarehouseInventoryVO> condition) {
        PageCommonVO<WarehouseInventoryVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize(), "a.material_no");
        if (!StringUtil.isNullOrEmpty(condition.getFilters().getMaterialName())) {
            condition.getFilters().setMaterialName(condition.getFilters().getMaterialName().replaceAll("\\s+", ""));
        }
        List<WarehouseInventoryVO> voList = new ArrayList<WarehouseInventoryVO>();
        List<WarehouseInventoryDO> doList = null;
        if (!StringUtil.isNullOrEmpty(condition.getFilters().getLocationCode())) {
            String locationCode = condition.getFilters().getLocationCode();
            if (locationCode.toCharArray()[0] == '\uFEFF') {
                locationCode = locationCode.substring(1);
            }
            condition.getFilters().setLocationCode(locationCode);
        }
        condition.getFilters().setMaterialsList(xcmg.device.infra.StringUtil.splitList(condition.getFilters().getMaterialsNos()));
        condition.getFilters().setLocationCodeList(filterLocationCode(condition.getFilters().getLocationCodes()));
        doList = warehouseInventoryMapper.listForDealer(condition.getFilters());
        for (WarehouseInventoryDO entity : doList) {
            WarehouseInventoryVO model = new WarehouseInventoryVO();
            BeanUtils.copyProperties(entity, model);
            model.setPrice(model.getPrice()==null?null:model.getPrice().divide(new BigDecimal(100)));
            voList.add(model);
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    public void exportDealerInventoryAll(WarehouseInventoryVO condition, String title) throws Exception {
        if (!StringUtil.isNullOrEmpty(condition.getMaterialName())) {
            condition.setMaterialName(condition.getMaterialName().replaceAll("\\s+", ""));
        }
        condition.setMaterialsList(xcmg.device.infra.StringUtil.splitList(condition.getMaterialsNos()));
        condition.setLocationCodeList(filterLocationCode(condition.getLocationCodes()));
        List<WarehouseInventoryDO> dataList = warehouseInventoryMapper.exportListForDealer(condition);
        invokeExport(dataList, title);
    }

    public PageCommonVO listStockAmountInfo(SearchCommonVO<StockAmountInfo> condition) throws Exception {
        StockAmountInfo stockAmountInfo = condition.getFilters();
        if (null == stockAmountInfo.getStartTime() || null == stockAmountInfo.getEndTime()) {
            throw new Exception("请选择时间段");
        }

        stockAmountInfo.setStartTime(DateUtil.getStartTimeOfDay(stockAmountInfo.getStartTime()));
        stockAmountInfo.setEndTime(DateUtil.getEndTimeOfDay(stockAmountInfo.getEndTime()));

        PageCommonVO<StockAmountInfo> pageCommonVO = new PageCommonVO();
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<StockAmountInfo> stockAmountInfos = warehouseInventoryMapper.listStockAmountInfo(stockAmountInfo);
        pageCommonVO.setPageInfo(new PageInfo(stockAmountInfos));
        pageCommonVO.setPageInfoList(stockAmountInfos);
        return pageCommonVO;
    }

    public void exportStockAmount(StockAmountInfo condition) throws Exception{
        if (null == condition.getStartTime() || null == condition.getEndTime()) {
            return;
        }

        condition.setStartTime(DateUtil.getStartTimeOfDay(condition.getStartTime()));
        condition.setEndTime(DateUtil.getEndTimeOfDay(condition.getEndTime()));
        List<StockAmountInfo> stockAmountInfos = warehouseInventoryMapper.listStockAmountInfo(condition);
        exportForStockAmount(stockAmountInfos);
    }

    private void exportForStockAmount(List<StockAmountInfo> doList) throws Exception {
        String title = "库存金额导出";
        String[] rowsName = new String[]{"序号", "零件编码", "零件名称", "零件分类", "单位",
                "单价", "结余库存", "结余金额", "入库数量", "出库数量", "在库数量", "库存金额"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < doList.size(); i++) {
            StockAmountInfo stockAmountInfo = doList.get(i);
            objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = stockAmountInfo.getMaterialsNo();
            objs[2] = stockAmountInfo.getMaterialsDes();
            objs[3] = stockAmountInfo.getMaterialsType();
            objs[4] = stockAmountInfo.getUnit();
            objs[5] = stockAmountInfo.getStandardPrice();
            objs[6] = stockAmountInfo.getBalanceQty();
            objs[7] = stockAmountInfo.getBalanceAmount();
            objs[8] = stockAmountInfo.getSelInboundQty();
            objs[9] = stockAmountInfo.getSelOutboundQty();
            objs[10] = stockAmountInfo.getCurrentStock();
            objs[11] = stockAmountInfo.getStockAmount();
            dataList.add(objs);
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    public BigDecimal getInventoryQty(String materialNo,String orgId){
       return warehouseInventoryMapper.getInventoryQty(materialNo,orgId);
    }

    public MaterialsEnableStock countEnableInventory(String orgId, String materialsNo) {
        return warehouseInventoryMapper.countEnableInventory(orgId, materialsNo);
    }

    /**
     * 查询代理商可用库存
     *
     * @param orgId
     * @param dealerCode
     * @param materialsNo
     * @return
     * @throws Exception
     */
    public MaterialsEnableStock countAgentEnableInventory(String orgId, String dealerCode, String materialsNo)
        throws Exception {
        CompanyDealerDO companyDealerDO = companyDealerMapper.itemByDealerCode(orgId, dealerCode);
        if(null == companyDealerDO || StringUtils.isBlank(companyDealerDO.getPlatOrgId())) {
            throw new Exception("未查询到代理商信息");
        }
        return warehouseInventoryMapper.countEnableInventory(companyDealerDO.getPlatOrgId(), materialsNo);
    }

    /**
     * 根据储位进行非条码零件转移
     * @param oldLocationCode 旧储位编码
     * @param newLocationCode 新储位编码
     * @param orgId 组织ID
     * @param userId 用户ID
     * @return 错误信息代码
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode transferByLocationWithoutBarCode(String oldLocationCode, String newLocationCode, String orgId, String userId) throws Exception{

        // TODO 将通用验证部分抽取私有方法，方法实现按照零件转移进行调整
        CompanyInfoVO companyInfoVO = companyInfoService.info(orgId);
        int companyInfoBarCode = companyInfoVO.getIsBarcode();

        //条码化企业检查
        if(1 == companyInfoBarCode){
            throw new Exception("该企业是条码化企业！无法进行非条码转库操作");
        }

        Map<String, Object> oldWarehouseMap = warehouseAreaLocationDOMapper.findAllCode(oldLocationCode, orgId);
        if (oldWarehouseMap == null || oldWarehouseMap.get("WAREHOUSE_CODE") == null || oldWarehouseMap.get("AREA_CODE") == null) {
            return ErrorCode.WarehouseLocationCodeError;
        }

        Map<String, Object> newWarehouseMap = warehouseAreaLocationDOMapper.findAllCode(newLocationCode, orgId);
        if (newWarehouseMap == null || newWarehouseMap.get("WAREHOUSE_CODE") == null || newWarehouseMap.get("AREA_CODE") == null) {
            return ErrorCode.WarehouseLocationCodeError;
        }

        //原仓库条码化仓库检查
        if(1 == warehouseDOMapper.itemByWarehouseCode(orgId, oldWarehouseMap.get("WAREHOUSE_CODE").toString()).getIsBarCode()) {
            throw new Exception("仓库：" + oldWarehouseMap.get("WAREHOUSE_CODE") + "，是条码化仓库");
        }

        //目标仓库条码化仓库检查
        if(1 == warehouseDOMapper.itemByWarehouseCode(orgId, newWarehouseMap.get("WAREHOUSE_CODE").toString()).getIsBarCode()){
            throw new Exception("仓库：" + newWarehouseMap.get("WAREHOUSE_CODE") + "，是条码化仓库");
        }



        WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
        inventoryVO.setOrgId(orgId);
        inventoryVO.setLocationCode((String) oldWarehouseMap.get("LOCATION_CODE"));
        inventoryVO.setIsOut(0);

        //旧储位零件查询
        List<WarehouseInventoryDO> oldInventoryDOs = warehouseInventoryMapper.list(inventoryVO);
        if (ListUtil.isNullOrEmpty(oldInventoryDOs)) {
            throw new Exception(oldWarehouseMap.get("LOCATION_CODE") + "，该储位下未找到零件");
        }

        WarehouseInventoryVO newInventoryVO = new WarehouseInventoryVO();
        newInventoryVO.setOrgId(orgId);
        newInventoryVO.setLocationCode(newWarehouseMap.get("LOCATION_CODE").toString());
        newInventoryVO.setIsOut(0);

        //新储位零件查询
        List<WarehouseInventoryDO> newInventoryDOs = warehouseInventoryMapper.list(newInventoryVO);

        Map<String, BigDecimal> materialNoAndAmounts = new HashMap<>();

        //判断是否存在相同的零件
        for (WarehouseInventoryDO newInventoryDO : newInventoryDOs) {
            for (WarehouseInventoryDO oldInventoryDO : oldInventoryDOs) {
                if(StringUtils.equals(oldInventoryDO.getMaterialNo(), newInventoryDO.getMaterialNo())){
                    //记录相同的零件编码和数量
                    materialNoAndAmounts.put(oldInventoryDO.getMaterialNo(), oldInventoryDO.getAmount());
                }
            }
        }

        //删除编码重复的零件
        WarehouseInventoryDO inventoryDO = new WarehouseInventoryDO();
        inventoryDO.setWarehouseCode(newWarehouseMap.get("WAREHOUSE_CODE").toString());
        inventoryDO.setAreaCode(newWarehouseMap.get("AREA_CODE").toString());
        inventoryDO.setOldLocationCode(oldLocationCode);
        inventoryDO.setOrgId(orgId);

        if(0 != materialNoAndAmounts.size()) {
            if (!(warehouseInventoryMapper.deleteByLocationCodeAndMaterialNos(inventoryDO, new ArrayList<>(materialNoAndAmounts.keySet())) > 0)) {
                throw new Exception("移动储位中的零件失败");
            }
        }

        inventoryDO = new WarehouseInventoryDO();

        inventoryDO.setWarehouseCode((String) newWarehouseMap.get("WAREHOUSE_CODE"));
        inventoryDO.setAreaCode((String) newWarehouseMap.get("AREA_CODE"));
        inventoryDO.setLocationCode(newLocationCode);
        inventoryDO.setLastChangeDate(new Date());
        inventoryDO.setLastChangeUser(userId);
        inventoryDO.setOldLocationCode(oldLocationCode);
        inventoryDO.setOrgId(orgId);

        //移动源储位中的零件到目标储位中
        warehouseInventoryMapper.updateByLocation(inventoryDO);

        inventoryDO = new WarehouseInventoryDO();
        inventoryDO.setWarehouseCode(newWarehouseMap.get("WAREHOUSE_CODE").toString());
        inventoryDO.setAreaCode(newWarehouseMap.get("AREA_CODE").toString());
        inventoryDO.setLocationCode(newLocationCode);
        inventoryDO.setLastChangeDate(new Date());
        inventoryDO.setLastChangeUser(userId);
        inventoryDO.setOldLocationCode(oldLocationCode);
        inventoryDO.setOrgId(orgId);

        //更新目标储位中已存在相同编码的零件的数量
        for (Map.Entry<String, BigDecimal> entry: materialNoAndAmounts.entrySet()) {
            if(!(warehouseInventoryMapper.updateAmountByLocationCodeAndMaterialNo(inventoryDO, entry.getKey(), entry.getValue()) > 0)){
                throw new Exception("更新零件数量失败");
            }
        }

        boolean success = this.addTransferRecord(oldWarehouseMap, newWarehouseMap, oldInventoryDOs, userId, orgId);
        if (!success) {
            throw new Exception("生成转库单失败");
        }

        return success ? ErrorCode.Success : ErrorCode.Failure;
    }

    /**
     * 非条码零件转移
     * @param warehouseInventoryTransferWithOutBarCodeVO 零件VO
     * @param orgId 组织ID
     * @param userId 用户ID
     * @return
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode transferByMaterialWithoutBarCode(WarehouseInventoryTransferWithOutBarCodeVO warehouseInventoryTransferWithOutBarCodeVO, String orgId, String userId) throws Exception{

        String oldLocationCode = warehouseInventoryTransferWithOutBarCodeVO.getOldLocationCode();
        String newLocationCode = warehouseInventoryTransferWithOutBarCodeVO.getNewLocationCode();

        CompanyInfoVO companyInfoVO = companyInfoService.info(orgId);
        int companyInfoBarCode = companyInfoVO.getIsBarcode();

        //条码化企业检查
        if(1 == companyInfoBarCode){
            throw new Exception("该企业是条码化企业！无法进行非条码转库操作");
        }

        Map<String, Object> oldWarehouseMap = warehouseAreaLocationDOMapper.findAllCode(oldLocationCode, orgId);
        if (oldWarehouseMap == null || oldWarehouseMap.get("WAREHOUSE_CODE") == null || oldWarehouseMap.get("AREA_CODE") == null) {
            return ErrorCode.WarehouseLocationCodeError;
        }

        Map<String, Object> newWarehouseMap = warehouseAreaLocationDOMapper.findAllCode(newLocationCode, orgId);
        if (newWarehouseMap == null || newWarehouseMap.get("WAREHOUSE_CODE") == null || newWarehouseMap.get("AREA_CODE") == null) {
            return ErrorCode.WarehouseLocationCodeError;
        }

        //原仓库条码化仓库检查
        if(1 == warehouseDOMapper.itemByWarehouseCode(orgId, oldWarehouseMap.get("WAREHOUSE_CODE").toString()).getIsBarCode()) {
            throw new Exception("仓库：" + oldWarehouseMap.get("WAREHOUSE_CODE") + "，是条码化仓库");
        }

        //目标仓库条码化仓库检查
        if(1 == warehouseDOMapper.itemByWarehouseCode(orgId, newWarehouseMap.get("WAREHOUSE_CODE").toString()).getIsBarCode()){
            throw new Exception("仓库：" + newWarehouseMap.get("WAREHOUSE_CODE") + "，是条码化仓库");
        }



        WarehouseInventoryVO inventoryVO = new WarehouseInventoryVO();
        inventoryVO.setOrgId(orgId);
        inventoryVO.setLocationCode((String) oldWarehouseMap.get("LOCATION_CODE"));
        inventoryVO.setIsOut(0);



        //旧储位零件查询(根据储位与零件编号)
        List<WarehouseInventoryDO> oldInventoryDOs = warehouseInventoryMapper.listByMaterialNos(orgId, oldLocationCode, warehouseInventoryTransferWithOutBarCodeVO.getMaterialNoAndAmounts());

        if (ListUtil.isNullOrEmpty(oldInventoryDOs)) {
            throw new Exception(oldWarehouseMap.get("LOCATION_CODE") + "，该储位下未找到零件");
        }

        List<MaterialNoAndAmountsVO> materialNoAndAmountsVOs = warehouseInventoryTransferWithOutBarCodeVO.getMaterialNoAndAmounts();

        //新储位零件查询
        List<WarehouseInventoryDO> newInventoryDOs = warehouseInventoryMapper.listByMaterialNos(orgId, newLocationCode, materialNoAndAmountsVOs);


        Map<String, MaterialNoAndAmountsVO> materialNoAndAmountsVOMap =
                materialNoAndAmountsVOs.stream().collect(Collectors.toMap(MaterialNoAndAmountsVO::getMaterialNo, materialNoAndAmountsVO -> materialNoAndAmountsVO));

        Map<String, WarehouseInventoryDO> oldInventoryDOMap = oldInventoryDOs.stream().
                collect(Collectors.toMap(WarehouseInventoryDO::getMaterialNo, oldInventoryDO -> oldInventoryDO));

        Map<String, WarehouseInventoryDO> newInventoryDOMap = newInventoryDOs.stream().
                collect(Collectors.toMap(WarehouseInventoryDO::getMaterialNo, newInventoryDO -> newInventoryDO));

        for (Map.Entry<String, MaterialNoAndAmountsVO> entry : materialNoAndAmountsVOMap.entrySet()) {
            //当扣减数量大于库存数量时
            if( 1 == entry.getValue().getAmounts().compareTo(oldInventoryDOMap.get(entry.getKey()).getAmount())){

                String message = "零件：{0}，编码{1}，移动数量大于库存数量！";
                throw new Exception(MessageFormat.format(message, oldInventoryDOMap.get(entry.getKey()).getMaterialName(), entry.getKey()));

            } else if (0 == entry.getValue().getAmounts().compareTo(oldInventoryDOMap.get(entry.getKey()).getAmount())){  // 当扣减数量等于库存数量的时候

                if( null == newInventoryDOMap.get(entry.getKey())){        //如果新储位中不存在该零件编码，直接更新零件所属储位

                    WarehouseInventoryDO warehouseInventoryDO = new WarehouseInventoryDO();
                    BeanUtils.copyProperties(oldInventoryDOMap.get(entry.getKey()), warehouseInventoryDO);
                    warehouseInventoryDO.setOldLocationCode(oldLocationCode);
                    warehouseInventoryDO.setLocationCode(newLocationCode);

                    warehouseInventoryDO.setWarehouseCode((String) newWarehouseMap.get("WAREHOUSE_CODE"));
                    warehouseInventoryDO.setAreaCode((String) newWarehouseMap.get("AREA_CODE"));

                    if( !(warehouseInventoryMapper.updateByLocationAndMaterialNo(warehouseInventoryDO) > 0)) {
                        throw new Exception("移动零件失败!");
                    }
                } else {                                         //如果新储位中存在相同的零件编码，删除零件并更新新储位中零件的数量

                    if( !(warehouseInventoryMapper.deleteByPrimaryKey(oldInventoryDOMap.get(entry.getKey()).getId()) > 0)){
                        throw new Exception("移动零件失败！");
                    }
                    if ( !(warehouseInventoryMapper.updateAmountByLocationCodeAndMaterialNo(newInventoryDOMap.get(entry.getKey()), entry.getKey(), entry.getValue().getAmounts()) >0 )){
                        throw new Exception("移动零件失败！");
                    }
                }

            } else if ( -1 == entry.getValue().getAmounts().compareTo(oldInventoryDOMap.get(entry.getKey()).getAmount())){   //当扣减数量少于库存数量

                if ( null == newInventoryDOMap.get(entry.getKey())) {      //如果新储位中不存在该零件编码，减少原有库存，插入需要转移的数量零件

                    WarehouseInventoryDO warehouseInventoryDO = new WarehouseInventoryDO();
                    BeanUtils.copyProperties(oldInventoryDOMap.get(entry.getKey()), warehouseInventoryDO);

                    if (!(warehouseInventoryMapper.updateAmountByLocationCodeAndMaterialNo(warehouseInventoryDO, entry.getKey(), entry.getValue().getAmounts().negate()) > 0 )){
                        throw new Exception("移动零件失败！");
                    }

                    WarehouseInventoryDO newWarehouseInventoryDO = new WarehouseInventoryDO();
                    BeanUtils.copyProperties(warehouseInventoryDO, newWarehouseInventoryDO);

                    ActionResult<String> textResult = fastGenClient.textGuid();

                    newWarehouseInventoryDO.setId(textResult.getValue());
                    newWarehouseInventoryDO.setAmount(entry.getValue().getAmounts());
                    newWarehouseInventoryDO.setLocationCode(newLocationCode);
                    newWarehouseInventoryDO.setWarehouseCode(newWarehouseMap.get("WAREHOUSE_CODE").toString());
                    newWarehouseInventoryDO.setAreaCode(newWarehouseMap.get("AREA_CODE").toString());
                    if (!(warehouseInventoryMapper.insert(newWarehouseInventoryDO) > 0)){
                        throw new Exception("移动零件失败！");
                    }

                } else {                                        //如果新储位中存在相同的零件编码，减少原库存，更新对应零件的数量

                    WarehouseInventoryDO warehouseInventoryDO = new WarehouseInventoryDO();
                    BeanUtils.copyProperties(oldInventoryDOMap.get(entry.getKey()), warehouseInventoryDO);
                    if ( !(warehouseInventoryMapper.updateAmountByLocationCodeAndMaterialNo(warehouseInventoryDO, entry.getKey(), entry.getValue().getAmounts().negate()) > 0)){
                        throw new Exception("移动零件失败！");
                    }

                    WarehouseInventoryDO newWarehouseInventoryDO = new WarehouseInventoryDO();
                    BeanUtils.copyProperties(warehouseInventoryDO, newWarehouseInventoryDO );
                    newWarehouseInventoryDO.setLocationCode(newLocationCode);

                    if ( !(warehouseInventoryMapper.updateAmountByLocationCodeAndMaterialNo(newWarehouseInventoryDO, entry.getKey(), entry.getValue().getAmounts()) > 0)){
                        throw new Exception("移动零件失败");
                    }
                }
            }
        }

        boolean success = this.addTransferRecord(materialNoAndAmountsVOMap,oldWarehouseMap, newWarehouseMap, oldInventoryDOs, userId, orgId);
        if (!success) {
            throw new Exception("生成转库单失败");
        }

        return success ? ErrorCode.Success : ErrorCode.Failure;
    }

    /**
     * 验证企业与仓库是否是条码化
     * @param orgId
     */
    private void validateOrgAndWarehouseBarCode(String orgId){

        //TO-DO 将验证条码化内容转移到该方法
    }

    /**
     * 零件转移转换单
     * @param materialNoAndAmountsVOMap
     * @param oldWarehouseMap
     * @param newWarehouseMap
     * @param inventoryDOList
     * @param userId
     * @param orgId
     * @return
     * @throws Exception
     */
    private boolean addTransferRecord(Map<String, MaterialNoAndAmountsVO> materialNoAndAmountsVOMap, Map<String, Object> oldWarehouseMap, Map<String, Object> newWarehouseMap, List<WarehouseInventoryDO> inventoryDOList, String userId, String orgId) throws Exception {
        MaterialTransferAddVO transferAddVO = new MaterialTransferAddVO();
        MaterialTransferVO transferVO = new MaterialTransferVO();
        List<MaterialTransferDetailVO> transferDetailVOList = new ArrayList<>();

        transferVO.setType(0);
        transferVO.setPreLocationCode((String) oldWarehouseMap.get("LOCATION_CODE"));
        transferVO.setPreAreaCode((String) oldWarehouseMap.get("AREA_CODE"));
        transferVO.setPreSapArea((String) oldWarehouseMap.get("SAP_CODE"));
        transferVO.setPreWarehouseCode((String) oldWarehouseMap.get("WAREHOUSE_CODE"));
        transferVO.setNewLocationCode((String) newWarehouseMap.get("LOCATION_CODE"));
        transferVO.setNewAreaCode((String) newWarehouseMap.get("AREA_CODE"));
        transferVO.setNewSapArea((String) newWarehouseMap.get("SAP_CODE"));
        transferVO.setNewWarehouseCode((String) newWarehouseMap.get("WAREHOUSE_CODE"));
        transferVO.setOrgId(orgId);

        for (WarehouseInventoryDO inventory : inventoryDOList) {
            MaterialTransferDetailVO transferDetailVO = new MaterialTransferDetailVO();
            BeanUtils.copyProperties(inventory, transferDetailVO);
            transferDetailVO.setBarcode(inventory.getBarCode());
            transferDetailVO.setAmount(materialNoAndAmountsVOMap.get(transferDetailVO.getMaterialNo()).getAmounts());
            transferDetailVOList.add(transferDetailVO);
        }
        transferAddVO.setHeaderInfo(transferVO);
        transferAddVO.setDetailList(transferDetailVOList);
        return materialTransferService.addPre(transferAddVO, userId, orgId).getCode() == 0;
    }


    /**
     * 根据零件id集合查询对应的中心仓库库存
     * @param meterialIds
     * @param orgId
     * @return
     */
    public Map<String, BigDecimal> queryCentralInventoryByMeterialIds(List<String> meterialIds, String orgId) {
        Map<String, BigDecimal> result = Maps.newHashMap();
        List<WarehouseInventoryDO> ll = warehouseInventoryMapper.queryCentralInventoryByMeterialIds(meterialIds, orgId);
        if (CollectionUtils.isEmpty(ll)) {
            return result;
        }

        for (WarehouseInventoryDO ddo : ll) {
            result.put(ddo.getMaterialNo(), ddo.getAmount());
        }
        return result;
    }


    /**
     * 库存查询接口内部逻辑混乱，而且以后可能改动，所以此处直接调用列表接口，不再重写，需要传入分页参数，默认给长一点
     * @param materialsNo
     * @param sapCode
     * @throws Exception
     */
    public Inventory4CRM getInventory4CRM(String materialsNo, String sapCode) throws Exception {
//        SearchCommonVO<WarehouseInventoryVO> condition,String departmentId

        Inventory4CRM inventory4CRM = new Inventory4CRM();
        inventory4CRM.setMaterialsNo(materialsNo);


        CompanyInfoDO companyInfoDO = companyInfoService.getBySapCode(sapCode);
        if (StringUtils.isBlank(materialsNo) || StringUtils.isBlank(sapCode)) {
            throw new Exception("参数异常");
        }
        if (null == companyInfoDO) {
            throw new Exception("sapCode异常");
        }

        WarehouseInventoryVO wiv = new WarehouseInventoryVO();
        // 此处用MaterialName是因为原先接口设计如此
        wiv.setMaterialName(materialsNo);
        wiv.setOrgId(companyInfoDO.getOrgId());
        wiv.setWarehouseCode(getWarehouseCode(sapCode));
        SearchCommonVO<WarehouseInventoryVO> condition = new SearchCommonVO<>();
        condition.setFilters(wiv);
        condition.setPageNum(1);
        condition.setPageSize(1000);
        PageCommonVO pageCommonVO = list(condition, FULL_PERMISSION_DEPT);

        if (null == pageCommonVO) {
            return inventory4CRM;
        }
        List<WarehouseInventoryVO> volist = pageCommonVO.getPageInfo().getList();;

        if (CollectionUtils.isEmpty(volist)) {
            return inventory4CRM;
        }

        BigDecimal amount = BigDecimal.ZERO;
        BigDecimal enableAmount = BigDecimal.ZERO;

        for (WarehouseInventoryVO inventoryVO : volist) {
            amount = amount.add(inventoryVO.getAmount());
            enableAmount = enableAmount.add(inventoryVO.getEnableNum());
        }
        inventory4CRM.setStockAmount(amount);
        inventory4CRM.setAvailableAmount(enableAmount);

        return inventory4CRM;
    }

    private String getWarehouseCode(String sapCode) {
        if ("2160".equals(sapCode)) {
            return "DLBJ";
        } else if ("2070".equals(sapCode)) {
            return "ZLBJ";
        }  else if ("2220".equals(sapCode)) {
            return "YHBJ";
        }
        return null;
    }

    public List<WarehouseInventoryDO> selectByMaterialNoAndOrgId(String materialNo,String orgId){
        return warehouseInventoryMapper.selectByMaterialNoAndOrgId(materialNo,orgId);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateSluggishFlagByMaterialNoAndOrgId(String materialNo,String orgId,String sluggishShardFlag){
        return warehouseInventoryMapper.updateSluggishFlagByMaterialNoAndOrgId(materialNo,orgId,sluggishShardFlag);
    }

    public PageCommonVO<WarehouseAreaStockQueryResultVO> areaStockList(SearchCommonVO<WarehouseAreaStockQueryParamVO> searchCondition) {
        //设置分页参数
        PageCommonVO<WarehouseAreaStockQueryResultVO> result = new PageCommonVO<>();
        PageHelperPlus.startPage(searchCondition.getPageNum(), searchCondition.getPageSize());
        WarehouseAreaStockQueryParamVO filters = searchCondition.getFilters();
        List<WarehouseAreaStockQueryResultVO> dataList = warehouseInventoryMapper.selectWarehouseAreaStock(filters);
        result.setPageInfo(new PageInfo(dataList));
        result.setPageInfoList(dataList);
        return result;
    }

    public List<WarehouseAreaStockQueryResultVO> areaStockListExport(WarehouseAreaStockQueryParamVO paramVO){
        List<WarehouseAreaStockQueryResultVO> dataList = warehouseInventoryMapper.selectWarehouseAreaStock(paramVO);
        return dataList;
    }
    
    public WarehouseStockInfoVO itemWarehouseInfo(WarehouseInfoConditionVO condition) throws Exception {
        String companyNo = condition.getCompanyNo();
        String orgId = getCompanyOrgIdByCode(companyNo);
        CompanyInfoDO companyInfoDO = companyInfoService.getByOrgId(orgId);
        if (companyInfoDO == null) {
            throw new Exception("公司不存在");
        }
        MaterialsVO materialsVO = materialsService.itemByNo(condition.getMaterialsNo(), orgId);
        if (materialsVO == null) {
            throw new Exception("零件信息不存在");
        }
        BigDecimal quantity = warehouseInventoryMapper.getInventoryQty(condition.getMaterialsNo(), orgId);
        WarehouseStockInfoVO warehouseStockInfoVO = new WarehouseStockInfoVO();
        warehouseStockInfoVO.setCompanyName(companyInfoDO.getCompanyName());
        warehouseStockInfoVO.setMaterialsNo(condition.getMaterialsNo());
        warehouseStockInfoVO.setMaterialsDes(materialsVO.getMaterialsDes());
        warehouseStockInfoVO.setOrgId(orgId);
        warehouseStockInfoVO.setQty(quantity == null ? BigDecimal.ZERO : quantity);
        warehouseStockInfoVO.setCompanyNo(condition.getCompanyNo());
        warehouseStockInfoVO.setUnit(materialsVO.getUnit());
        return warehouseStockInfoVO;
    }
    
    private String getCompanyOrgIdByCode(String erpCode) throws Exception {
        List<String> orgIds = companyDealerMapper.listOrgIdByCode(erpCode, companyUtil.ynOrgId());
        if (CollectionUtils.isEmpty(orgIds)) {
            throw new Exception("公司不存在");
        }
        if (orgIds.size() > 1) {
            throw new Exception("公司不唯一");
        }
        return orgIds.get(0);
    }

    @Data
    private class Inventory4CRM {

        private String materialsNo;

        private BigDecimal stockAmount;

        private BigDecimal availableAmount;
    }

}
